【问题标题】:Drag Vertices of mesh with mouse unity用鼠标统一拖动网格的顶点
【发布时间】:2018-06-12 11:31:08
【问题描述】:

我想做一些类似这个视频的事情。 https://www.youtube.com/watch?v=ioiaDXOI6zI

我希望能够像使用鼠标或键盘输入的视频一样变形网格和改变形状。我正在寻找一种轻松的方法来完成这项工作,因为每次更改顶点时都会创建一个新的网格,这在性能方面非常重要。我也想比较两个网格是否相似,但我坚持这一点,不胜感激任何帮助或指导。谢谢

这是我目前的代码:

public class MeshDeformation: MonoBehaviour {

   MeshFilter mf;
   Vector3[] verts;

   public Vector3 value = new Vector3(0.01f,0.01f,0.01f);

   void Start () {
       mf = GetComponent<MeshFilter>();
       verts = mf.mesh.vertices;
       Debug.Log("Vertices" + verts.Length);
   }

   // Update is called once per frame
   void Update () {
       if(Input.GetMouseButton(0))
       {
           RaycastHit hit;
           Vector3 input = Camera.main.ScreenToWorldPoint(Input.mousePosition);
           Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

           if(Physics.Raycast(ray,out hit, 300))
           {
               Vector3 hitVertices = FindNearestPoint(hit.point);
               RaisePoint(hitVertices,value);
               Debug.Log("coming inside");
           }
       }
   }
   private Vector3 FindNearestPoint(Vector3 point)
   {
       Vector3 NearestPoint = new Vector3();
       float lastDistance = 99999999f;

       for (int i = 0; i < verts.Length; i++)
       {
           float distance = GetDistance(point, verts[i]);
           if (distance < lastDistance)
           {
               lastDistance = distance;
               NearestPoint = verts[i];
           }
       }
       return NearestPoint;
   }

   private float GetDistance(Vector3 start, Vector3 end)
   {
       return Mathf.Sqrt(Mathf.Pow((start.x - end.x), 2) + Mathf.Pow((start.y - end.y), 2) + Mathf.Pow((start.z - end.z), 2));
   }

   private void RaisePoint(Vector3 point, Vector3 val)
   {
       int index = -1;
       for (int i = 0; i < verts.Length; i++)
       {
           if (verts[i] == point)
           {
               index = i;
               break;
           }
       }

       if (index == -1)
       {
           Debug.LogError("Could not match points");
       }
       else 
       {
           Vector3 newPoint = verts[index];
           newPoint += val;
           verts[index] = newPoint;
          // mf.mesh.Clear();
           mf.mesh.vertices = verts;
           mf.mesh.RecalculateNormals();
           mf.mesh.RecalculateBounds(); 
       }
   }
}

【问题讨论】:

    标签: unity3d mesh


    【解决方案1】:

    您想要执行 Mesh documentation 中看到的场景 2:

    1. 每帧修改顶点属性:
      a) 获取顶点
      b) 修改它们
      c) 将它们分配回网格。

    因此,您根本不希望调用 Clear()(您现在已将其注释掉,但它是不需要的,仅包含在场景 3 中)。

    同样,RecalculateNormals()RecalculateBounds() 可能非常密集。您可能希望延迟执行这些操作,直到用户释放鼠标按钮。网格在修改过程中会有不适当的阴影,但这可能是可以接受的损失。

    否则您的代码看起来非常接近文档中的示例。

    还要注意 Debug.Log(...) 引入了相当多的开销,并且每帧调用它也可能会减慢速度。尝试将这些注释掉,看看您的性能问题是否消失,并与删除重新计算命令进行比较。

    【讨论】:

    • 感谢分享信息。我真正想要的是单击网格并将我单击的那些顶点沿鼠标移动的方向拖动。我尝试将鼠标位置添加到投射光线的最近顶点,但它不起作用。能指导一下吗?
    • @imrankhan 这听起来像是一个新问题。在任何情况下我都没有任何见解。
    猜你喜欢
    • 2014-09-23
    • 1970-01-01
    • 2013-03-12
    • 1970-01-01
    • 2019-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-02
    相关资源
    最近更新 更多