美文网首页Unity技术分享
Mesh顶点自由修改

Mesh顶点自由修改

作者: ealton | 来源:发表于2017-11-29 10:16 被阅读16次

有的时候,单单修改一个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

相关文章

  • Mesh顶点自由修改

    有的时候,单单修改一个Mesh的中心点,旋转角度,和Scale并不能满足需求,比如有的时候,我们想让一个模型桥的边...

  • libGdx使用mesh画线

    使用mesh画线,并贴上纹理。画线类 控制顶点 效果:

  • Unity Mesh 立方体以及UV

    首先我们要知道创建mesh需要哪些组件 mesh的属性 1.顶点坐标(vertex)2.法线(normal)3.纹...

  • 最简单的顶点、片元着色器_02

    shader 的输入输出流程:1.由Mesh传入顶点数据,进入顶点着色器函数(vert),每个顶点执行一次这个函...

  • RhinoCommon Mesh.Vertices.Combin

    RhinoCommon 中对Mesh 进行顶点焊接,可以使用CombineIdentical方法,参考代码如下: ...

  • UGUI(1) 基础理解 -- 绘制、重绘、事件系统

    目录: 如何绘制 如何响应点击 -事件系统 如何重绘ReBuild 1. 如何绘制 将顶点数据填充到Mesh,再将...

  • 使用Dx11渲染纹理3——渲染矩形

    渲染矩形 渲染矩形只需要将顶点及顶点索引做修改,建立两个三角形,并且修改图元拓扑为:IASetPrimitiveT...

  • 010.mesh编程入门

    1.任何物体都是由mesh构成2.mesh是由若干个三角形组成3.三角形三个顶点组成顺时针为正面,逆时针为背面4....

  • OpenGLES的理解

    参数含义:index: 指定要修改的顶点着色器中顶点变量id;size: 指定每个顶点属性的组件数量。必须为1、2...

  • [Unity 3d] VertexPaint (Mesh 顶点画

    一个 Mesh 顶点动画绘制工具。 GitHub 上的工程多如繁星,有些好的仓库,但凡不经意间错过了就很难找回,故...

网友评论

    本文标题:Mesh顶点自由修改

    本文链接:https://www.haomeiwen.com/subject/grtubxtx.html