在 Unity 中变形网格以在运行时对齐参考点
Deform a Mesh in Unity to Align Reference Points at Runtime
经过 2 天的研究和尝试不同的 tutorials/approaches 试图掌握这个问题,我放弃了。
我已经解释了我在这个 YouTube 视频中完全想要实现的目标...
https://youtu.be/GJ6Du0EENhc - 7 分钟
这个简化的问题:
在我的测试场景中,我在容器中有一架飞机。容器内还有一个称为“modelref”的球体,其位置与平面相交。容器外面是另一个球体,叫做 'realworldref'.
我想做的是按下一个按钮,模型参考将移动到现实世界参考的位置。同时,它应该从平面中拖动顶点,使得最接近 modelref 的顶点一直被拉到新位置,效果消散到半径 'influence area'(最终将被定义通过盒子对撞机)。
我试过的:
我做了一些简单的步骤(省略了影响半径),但我的大脑无法掌握方向、矢量、大小等……所以平面的顶点甚至没有在正确的方向上移动正确的距离。
这是我在 modelref 上的当前脚本:
public void HandleInput() //responds to mouse click
{
Vector3 heading = (realWorldRef.transform.position - this.transform.position);
float distance = heading.magnitude;
Vector3 dir = heading / distance;
this.transform.position = realWorldRef.transform.position;
MeshDeformer deformer = colliderOfMeshToDeform.GetComponent<MeshDeformer>();
if (deformer)
{
deformer.DeformByDirectionAndDistance(heading, dir, distance);
}
}
那么这是 MeshDeformer 脚本:
public class MeshDeformer:MonoBehaviour
{
Mesh deformingMesh;
Vector3[] originalVertices, displacedVertices;
void Start()
{
deformingMesh = GetComponent<MeshFilter>().mesh;
originalVertices = deformingMesh.vertices;
displacedVertices = new Vector3[originalVertices.Length];
for (int i = 0; i < originalVertices.Length; i++)
{
displacedVertices[i] = originalVertices[i];
}
}
internal void DeformByDirectionAndDistance(Vector3 heading, Vector3 normalisedDir, float distance)
{
for (int i = 0; i < displacedVertices.Length; i++)
{
MoveVerticesByDirectionAndDistance(i, heading, normalisedDir, distance);
}
}
private void MoveVerticesByDirectionAndDistance(int i, Vector3 heading, Vector3 normalisedDir, float distance)
{
displacedVertices[i] += normalisedDir * distance; //this is the bit that is wrong...
deformingMesh.vertices = displacedVertices;
deformingMesh.RecalculateNormals();
}
}
目前平面的所有顶点都在移动,但移动量很小,而且方向似乎不正确。在第一阶段,我只是尝试将平面的所有顶点移动到与重新定位以匹配 realworldRef.transform.
时 modelRef 移动完全相同的距离和方向
在此之后,我会尝试添加一个 'area of influence',它会随着与原始模型参考位置的距离而下降。因此,最近的顶点移动了整个距离,距离较远的顶点移动较少。
非常感谢任何帮助。
方向在世界space中,所以如果你想沿着它移动顶点,你应该先把它转换成模型space。
var dir2 = modelObject.transform.InverseTransformVector(dir.normalized * distance);
modelObject
是mesh filter组件附着的对象。 distance
是你想在世界上移动的距离space。
现在您可以沿新方向移动顶点。
displacedVertices[i] += dir2;
经过 2 天的研究和尝试不同的 tutorials/approaches 试图掌握这个问题,我放弃了。
我已经解释了我在这个 YouTube 视频中完全想要实现的目标... https://youtu.be/GJ6Du0EENhc - 7 分钟
这个简化的问题: 在我的测试场景中,我在容器中有一架飞机。容器内还有一个称为“modelref”的球体,其位置与平面相交。容器外面是另一个球体,叫做 'realworldref'.
我想做的是按下一个按钮,模型参考将移动到现实世界参考的位置。同时,它应该从平面中拖动顶点,使得最接近 modelref 的顶点一直被拉到新位置,效果消散到半径 'influence area'(最终将被定义通过盒子对撞机)。
我试过的: 我做了一些简单的步骤(省略了影响半径),但我的大脑无法掌握方向、矢量、大小等……所以平面的顶点甚至没有在正确的方向上移动正确的距离。
这是我在 modelref 上的当前脚本:
public void HandleInput() //responds to mouse click
{
Vector3 heading = (realWorldRef.transform.position - this.transform.position);
float distance = heading.magnitude;
Vector3 dir = heading / distance;
this.transform.position = realWorldRef.transform.position;
MeshDeformer deformer = colliderOfMeshToDeform.GetComponent<MeshDeformer>();
if (deformer)
{
deformer.DeformByDirectionAndDistance(heading, dir, distance);
}
}
那么这是 MeshDeformer 脚本:
public class MeshDeformer:MonoBehaviour {
Mesh deformingMesh;
Vector3[] originalVertices, displacedVertices;
void Start()
{
deformingMesh = GetComponent<MeshFilter>().mesh;
originalVertices = deformingMesh.vertices;
displacedVertices = new Vector3[originalVertices.Length];
for (int i = 0; i < originalVertices.Length; i++)
{
displacedVertices[i] = originalVertices[i];
}
}
internal void DeformByDirectionAndDistance(Vector3 heading, Vector3 normalisedDir, float distance)
{
for (int i = 0; i < displacedVertices.Length; i++)
{
MoveVerticesByDirectionAndDistance(i, heading, normalisedDir, distance);
}
}
private void MoveVerticesByDirectionAndDistance(int i, Vector3 heading, Vector3 normalisedDir, float distance)
{
displacedVertices[i] += normalisedDir * distance; //this is the bit that is wrong...
deformingMesh.vertices = displacedVertices;
deformingMesh.RecalculateNormals();
}
}
目前平面的所有顶点都在移动,但移动量很小,而且方向似乎不正确。在第一阶段,我只是尝试将平面的所有顶点移动到与重新定位以匹配 realworldRef.transform.
时 modelRef 移动完全相同的距离和方向在此之后,我会尝试添加一个 'area of influence',它会随着与原始模型参考位置的距离而下降。因此,最近的顶点移动了整个距离,距离较远的顶点移动较少。
非常感谢任何帮助。
方向在世界space中,所以如果你想沿着它移动顶点,你应该先把它转换成模型space。
var dir2 = modelObject.transform.InverseTransformVector(dir.normalized * distance);
modelObject
是mesh filter组件附着的对象。 distance
是你想在世界上移动的距离space。
现在您可以沿新方向移动顶点。
displacedVertices[i] += dir2;