Mesh顶点自由修改

有的时候,单单修改一个Mesh的中心点,旋转角度,和Scale并不能满足需求,比如有的时候,我们想让一个模型桥的边稍微变宽点来满足程序上的需求,通过拉伸的话模型比例就变了,这个时候要是能找到我们需要拉伸的点,然后手动把他们进行拉伸,那就省去了美术修改的时间了,而且更关键的是作为程序,我们可以准确的知道我们需要的位置,也能省去不少跟美术沟通的时间。

using UnityEngine;
using UnityEngine.EventSystems;


namespace LDFW.Model
{


    public class MeshManipulator : MonoBehaviour, IPointerClickHandler
    {

        public Camera                   raycastingCamera;
        public Transform                draggingSphere;
        
        [ContextMenuItem("Save", "SaveMesh")]
        public string                   savePath = "Assets/";

        private Transform               vertexSphere;
        private int                     vertexSphereReferencingIndex;
        private Mesh                    originalMesh;
        private Mesh                    currentMesh;
        private MeshCollider            meshCollider;
        private Vector3[]               originalVertices;
        private Vector3[]               currentVertices;
        private Vector3                 meshSize;
        private int                     vertexCount;

        private void Start()
        {
            MeshFilter meshFilter = GetComponent<MeshFilter>();

            if (meshFilter != null)
            {
                originalMesh = meshFilter.mesh;
                currentMesh = MeshGenerator.DuplicateMesh(originalMesh);
                meshFilter.mesh = currentMesh;
                meshSize = currentMesh.bounds.size;

                originalVertices = originalMesh.vertices;
                currentVertices = currentMesh.vertices;
                vertexCount = originalVertices.Length;

                foreach (var collider in GetComponents<Collider>())
                    DestroyImmediate(collider);

                meshCollider = gameObject.AddComponent<MeshCollider>();

                if (raycastingCamera == null)
                    raycastingCamera = Camera.main;
            }
        }

#if UNITY_EDITOR
        private void Update()
        {
            if (vertexSphere != null)
            {

                currentVertices[vertexSphereReferencingIndex] = vertexSphere.localPosition;
                currentMesh.vertices = currentVertices;
            }
        }
#endif

        public void OnPointerClick(PointerEventData eventData)
        {
            Debug.Log("OnPointerClick");
            RaycastHit hit;
            Ray ray = raycastingCamera.ScreenPointToRay(eventData.position);
            if (meshCollider.Raycast(ray, out hit, raycastingCamera.farClipPlane))
            {
                Debug.Log("hit point = " + hit.point);
                if (vertexSphere != null)
                    Destroy(vertexSphere.gameObject);

                //vertexSphereReferencingIndex = closestVertexIndex;
                vertexSphere = Instantiate(draggingSphere.gameObject).transform;
                vertexSphere.name = "vertex";
                vertexSphere.SetParent(transform);
                vertexSphere.position = hit.point;
                vertexSphere.gameObject.SetActive(true);

                vertexSphereReferencingIndex = FindClosestVertexIndex(vertexSphere.localPosition);
                vertexSphere.localPosition = currentVertices[vertexSphereReferencingIndex];

                Debug.Log("Closest point = " + currentVertices[vertexSphereReferencingIndex].ToString());
            }
        }

        private int FindClosestVertexIndex(Vector3 position)
        {
            Debug.Log("position = " + position.ToString());
            int closestIndex = -1;
            float shortestDistance = float.MaxValue;
            float currentDistance;
            for (int i = 0; i < vertexCount; i++)
            {
                currentDistance = (currentVertices[i] - position).magnitude;
                if (currentDistance < shortestDistance)
                {
                    shortestDistance = currentDistance;
                    closestIndex = i;
                }
            }

            return closestIndex;
        }

        public Mesh GetCurrentMesh()
        {
            return currentMesh;
        }

        public void SaveMesh()
        {
            LDFW.Tools.SaveToDisk.SaveAssetToFile(currentMesh, savePath);
        }

    }

}

来试验下,这个是原来的模型:


image.png

然后我们来改变一下里面闪电的大小:


image.png
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容