网格编辑脚本
功能:实现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插件