最近在搞軟件底層開發,將一些工具或者底層腳本打成dll導入unity使用,有這樣一需求,就是編輯功能,須要像Scene場景同樣,實現那種編輯軸數組
建立Mesh,構建編輯軸,這個地方這麼幾步:ide
1.線(軸)工具
2.圓(旋轉線)this
3.正方形(軸面)spa
4.圓錐(軸方向)code
代碼:orm
1 /// <summary> 2 /// 建立線Mesh 3 /// </summary> 4 /// <param name="start">線起點</param> 5 /// <param name="end">線終點</param> 6 /// <returns>Mesh對象</returns> 7 private Mesh CreateLineMesh(Vector3 start, Vector3 end) 8 { 9 var vertices = new List<Vector3> { start, end }; 10 var indices = new List<int> { 0, 1 }; 11 12 Mesh mesh = new Mesh(); 13 mesh.SetVertices(vertices); 14 mesh.SetIndices(indices.ToArray(), MeshTopology.Lines, 0); 15 16 return mesh; 17 }
這就建立一條起點爲start,終點爲end的線,是這樣,這裏在建立是經過Mesh的拓撲結構MeshTopology實現的,MeshTopology是一個枚舉,對象
使用SetIndices去賦值索引,參數分別是索引數組,選擇的拓撲結構,要修改的子網格,還有兩種重載本身去查。blog
代碼:索引
1 /// <summary> 2 /// 建立(旋轉)圓圈Mesh 3 /// </summary> 4 /// <param name="radius">圓圈半徑</param> 5 /// <returns></returns> 6 private Mesh CreateCircleMesh(float radius) 7 { 8 List<Vector3> vertexList = new List<Vector3>(); 9 List<int> indexList = new List<int>(); 10 for (float i = 0; i < 360.0f; i += 5.0f) 11 { 12 float rad = Mathf.Deg2Rad * i; 13 float cosA = Mathf.Cos(rad); 14 float sinA = Mathf.Sin(rad); 15 vertexList.Add(new Vector3(radius * cosA, radius * sinA, 0)); 16 if (i != 0) 17 { 18 vertexList.Add(new Vector3(radius * cosA, radius * sinA, 0)); 19 } 20 } 21 vertexList.Add(new Vector3(radius * Mathf.Cos(Mathf.Deg2Rad * 0), radius * Mathf.Sin(Mathf.Deg2Rad * 0), 0)); 22 for (int i = 0; i < 144; i++) 23 { 24 indexList.Add(i); 25 } 26 Mesh mesh = new Mesh(); 27 mesh.SetVertices(vertexList); 28 mesh.SetIndices(indexList.ToArray(), MeshTopology.Lines, 0); 29 return mesh; 30 }
代碼中144=(360/5)*2(端點相連問題)
當時這裏的實現思路我想了三種:
1.使用Mesh,本身建立圓面(倆圓面建立出圓圈)
2.LineRender畫圓
1 //private LineRenderer line; 2 //private int r = 20; 3 //private int n = 360; 4 ///lineRender畫圓 5 //void Start() 6 //{ 7 // line = this.GetComponent<LineRenderer>(); 8 // line.positionCount = 360 + 1; 9 // for (int i = 0; i < n + 1; i++) 10 // { 11 // //劃線的話2D座標就好了,這裏咱們計算x和z座標軸上的座標,而y永遠是0 12 // //計算x和z的長度,乘以半徑r來獲得最終長度 13 // float x = Mathf.Cos((360 * (i + 1) / n) * Mathf.Deg2Rad) * r; 14 // float z = Mathf.Sin((360 * (i + 1) / n) * Mathf.Deg2Rad) * r; 15 // //設置座標畫線 16 // line.SetPosition(i, new Vector3(0, x, z)); 17 // } 18 //}
1 /// <summary> 2 /// 使用Mesh畫兩個圓面組成的圓環 3 /// </summary> 4 /// <param name="radius"></param> 5 /// <param name="innerradius"></param> 6 /// <param name="angledegree"></param> 7 /// <param name="segments"></param> 8 /// <returns></returns> 9 Mesh CreateMesh(float radius, float innerradius, float angledegree, int segments) 10 { 11 //vertices(頂點): 12 int vertices_count = segments * 2 + 2; //由於vertices(頂點)的個數與triangles(索引三角形頂點數)必須匹配 13 Vector3[] vertices = new Vector3[vertices_count]; 14 float angleRad = Mathf.Deg2Rad * angledegree; 15 float angleCur = angleRad; 16 float angledelta = angleRad / segments; 17 for (int i = 0; i < vertices_count; i += 2) 18 { 19 float cosA = Mathf.Cos(angleCur); 20 float sinA = Mathf.Sin(angleCur); 21 vertices[i] = new Vector3(radius * cosA, 0, radius * sinA); 22 vertices[i + 1] = new Vector3(innerradius * cosA, 0, innerradius * sinA); 23 angleCur -= angledelta; 24 } 25 //triangles: 26 int triangle_count = segments * 6; 27 int[] triangles = new int[triangle_count]; 28 for (int i = 0, vi = 0; i < triangle_count; i += 6, vi += 2) 29 { 30 triangles[i] = vi; 31 triangles[i + 1] = vi + 3; 32 triangles[i + 2] = vi + 1; 33 triangles[i + 3] = vi + 2; 34 triangles[i + 4] = vi + 3; 35 triangles[i + 5] = vi; 36 } 37 //負載屬性與mesh 38 Mesh mesh = new Mesh(); 39 mesh.vertices = vertices; 40 mesh.triangles = triangles; 41 //mesh.uv = uvs; 42 mesh.RecalculateNormals(); 43 return mesh; 44 }
代碼:
1 /// <summary> 2 /// 建立正方形面Mesh 3 /// </summary> 4 /// <param name="size">面尺寸</param> 5 /// <returns>Mesh對象</returns> 6 private Mesh CreatePlaneMesh(Vector2 size) 7 { 8 var vertices = new List<Vector3>(); 9 var indices = new List<int>(); 10 11 var x = size.x * 0.5f; 12 var z = size.y * 0.5f; 13 14 vertices.Add(new Vector3(x, 0.0f, z)); 15 vertices.Add(new Vector3(-x, 0.0f, z)); 16 vertices.Add(new Vector3(-x, 0.0f, -z)); 17 vertices.Add(new Vector3(x, 0.0f, -z)); 18 19 indices.Add(0); 20 indices.Add(1); 21 indices.Add(2); 22 indices.Add(0); 23 indices.Add(2); 24 indices.Add(3); 25 26 Mesh mesh = new Mesh(); 27 mesh.SetVertices(vertices); 28 mesh.SetTriangles(indices, 0); 29 mesh.RecalculateNormals(); 30 31 return mesh; 32 }
這個就不說啥了,前面說過建立立方體了。
1 /// <summary> 2 /// 建立圓錐Mesh 3 /// </summary> 4 /// <param name="radius">圓錐底面半徑</param> 5 /// <param name="height">圓錐高度</param> 6 /// <returns>Mesh對象</returns> 7 private Mesh CreateConeMesh(float radius, float height) 8 { 9 var vertices = new List<Vector3>(); 10 var indices = new List<int>(); 11 12 vertices.Add(Vector3.zero); 13 vertices.Add(Vector3.up * height); 14 15 var temp = new List<Vector3>(); 16 //底圓面 17 for (var i = 0.0f; i < 360.0f; i += 30) 18 { 19 var rad = Mathf.Deg2Rad * i; 20 var x = radius * Mathf.Cos(rad); 21 var z = radius * Mathf.Sin(rad); 22 23 temp.Add(new Vector3(x, 0.0f, z)); 24 } 25 26 vertices.AddRange(temp); 27 vertices.AddRange(temp); 28 29 for (var i = 2; i <= 13; i++) 30 { 31 indices.Add(i); 32 if (i < 13) 33 { 34 indices.Add(i + 1); 35 } 36 else 37 { 38 indices.Add(2); 39 } 40 indices.Add(0); 41 } 42 43 for (var i = 14; i <= 25; i++) 44 { 45 indices.Add(i); 46 indices.Add(1); 47 if (i < 25) 48 { 49 indices.Add(i + 1); 50 } 51 else 52 { 53 indices.Add(14); 54 } 55 } 56 57 Mesh mesh = new Mesh(); 58 mesh.SetVertices(vertices); 59 mesh.SetTriangles(indices, 0); 60 mesh.RecalculateNormals(); 61 62 return mesh; 63 }
到這就須要的編輯軸物件都建立完成了。
效果圖: