網格編輯腳本

網格編輯腳本

功能:實現UnityGame視圖下對模型形狀的編輯。

using UnityEngine;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class MeshEditor : MonoBehaviour {
    #region 變量

    //頂點大小
    [SerializeField, Range(0, 1)]
    public float _VertexSize = 0.05f;
    //頂點大小緩存
    [System.NonSerialized]
    public float _LastVertexSize;
    //頂點數量
    [SerializeField]
    public int _VertexNumber = 0;
    //最大處理頂點數
    [System.NonSerialized]
    public int _VertexNum = 5000;
    //所有頂點物體集合
    [System.NonSerialized]
    public GameObject[] _Vertices = new GameObject[0];
    //物體網格
    [System.NonSerialized]
    public Mesh _Mesh;
    //頂點物體數量
    [System.NonSerialized]
    public int _VerticesNum = 0;
    //所有重複頂點集合
    [System.NonSerialized]
    public List<List<int>> _AllVerticesGroupList;
    //所有頂點集合
    [System.NonSerialized]
    public List<Vector3> _AllVerticesList;
    //記錄所有頂點集合
    [System.NonSerialized]
    public List<Vector3> _RecordAllVerticesList;
    //篩選後的頂點集合
    [System.NonSerialized]
    public List<Vector3> _VerticesList;
    //所有需移除的頂點集合
    [System.NonSerialized]
    public List<int> _VerticesRemoveList;
    //用於篩選的頂點集合
    [System.NonSerialized]
    public List<int> _VerticesSubList;
    //頂點動畫數組
    [System.NonSerialized]
    public List<Vector3[]> _VerticesAnimationArray = new List<Vector3[]>();
    //動畫播放中
    [System.NonSerialized]
    public bool _IsPlay = false;
    //當前選中的幀
    [System.NonSerialized]
    public int _NowSelectFrame = -1;

    //動畫播放序列
    private int _AnimationIndex;
    //動畫播放上一序列
    private int _AnimationLastIndex;
    //動畫播放片段
    private Vector3[] _AnimationFragment;
    //動畫播放控制器
    private int _AnimationPlayControl;
    //動畫播放速度(每幀刷新1/30個片段),越小播放越快
    private int _AnimationPlaySpeed = 30;
    #endregion

    void Start ()
    {
        MeshVertexIdentity();
    }

    void Update () {
        RefishMesh();
    }

    void MeshVertexIdentity()
    {
        #region 識別頂點
        _AllVerticesGroupList = new List<List<int>>();
        _AllVerticesList = new List<Vector3>(GetComponent<MeshFilter>().sharedMesh.vertices);
        _RecordAllVerticesList = new List<Vector3>(GetComponent<MeshFilter>().sharedMesh.vertices);
        _VerticesList = new List<Vector3>(GetComponent<MeshFilter>().sharedMesh.vertices);
        _VerticesRemoveList = new List<int>();

        //循環遍歷並記錄重複頂點
        for (int i = 0; i < _VerticesList.Count; i++)
        {
            EditorUtility.DisplayProgressBar("識別頂點", "正在識別頂點(" + i + "/" + _VerticesList.Count + ")......", 1.0f / _VerticesList.Count * i);
            //已存在於刪除集合的頂點不計算
            if (_VerticesRemoveList.IndexOf(i) >= 0)
                continue;

            _VerticesSubList = new List<int>();
            _VerticesSubList.Add(i);
            int j = i + 1;
            //發現重複頂點,將之記錄在內,並加入待刪除集合
            while (j < _VerticesList.Count)
            {
                if (_VerticesList[i] == _VerticesList[j])
                {
                    _VerticesSubList.Add(j);
                    _VerticesRemoveList.Add(j);
                }
                j++;
            }
            //記錄重複頂點集合
            _AllVerticesGroupList.Add(_VerticesSubList);
        }
        //整理待刪除集合
        _VerticesRemoveList.Sort();
        //刪除重複頂點
        for (int i = _VerticesRemoveList.Count - 1; i >= 0; i--)
        {
            _VerticesList.RemoveAt(_VerticesRemoveList[i]);
        }
        _VerticesRemoveList.Clear();
        #endregion
        #region 創建頂點
        _VerticesNum = _VerticesList.Count;
        _VertexNumber = _VerticesNum;
        //創建頂點,應用頂點大小設置,頂點位置爲刪除重複頂點之後的集合
        _Vertices = new GameObject[_VerticesNum];
        for (int i = 0; i < _VerticesNum; i++)
        {
            EditorUtility.DisplayProgressBar("創建頂點", "正在創建頂點(" + i + "/" + _VerticesNum + ")......", 1.0f / _VerticesNum * i);
            _Vertices[i] = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            _Vertices[i].name = "Vertex";
            _Vertices[i].transform.localScale = new Vector3(_VertexSize, _VertexSize, _VertexSize);
            _Vertices[i].transform.position = transform.localToWorldMatrix.MultiplyPoint3x4(_VerticesList[i]);
            _Vertices[i].GetComponent<MeshRenderer>().sharedMaterial = GetComponent<MeshRenderer>().sharedMaterial;
            _Vertices[i].AddComponent<Vertex>();
            _Vertices[i].GetComponent<Vertex>()._Identity = i;
            //_Vertices[i].GetComponent<Vertex>()._MeshAnimation = this;
            _Vertices[i].GetComponent<Vertex>()._TheBoneName = "None";
            _Vertices[i].transform.SetParent(transform);
        }
        _LastVertexSize = _VertexSize;
        //重構網格
        _Mesh = new Mesh();
        _Mesh.Clear();
        _Mesh.vertices = _AllVerticesList.ToArray();
        _Mesh.triangles = GetComponent<MeshFilter>().sharedMesh.triangles;
        _Mesh.uv = GetComponent<MeshFilter>().sharedMesh.uv;
        _Mesh.name = GetComponent<MeshFilter>().sharedMesh.name;
        _Mesh.RecalculateNormals();
        GetComponent<MeshFilter>().sharedMesh = _Mesh;
        EditorUtility.ClearProgressBar();
        #endregion
    }

    /// <summary>
    /// 刷新網格
    /// </summary>
    void RefishMesh()
    {
        if (_Mesh != null)
        {
            //重新應用頂點位置
            for (int i = 0; i < _Vertices.Length; i++)
            {
                for (int j = 0; j < _AllVerticesGroupList[i].Count; j++)
                {
                    _AllVerticesList[_AllVerticesGroupList[i][j]] = transform.worldToLocalMatrix.MultiplyPoint3x4(_Vertices[i].transform.position);
                }
            }
            //刷新網格
            _Mesh.vertices = _AllVerticesList.ToArray();
            _Mesh.RecalculateNormals();
        }
    }
}

link text :Mesh Editor插件

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章