網格編輯腳本
功能:實現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插件