using UnityEngine; using System.Collections.Generic; using System.Reflection; using System; namespace UnityEngine.Rendering { /// /// Helper to build and render a mesh for Gizmos, it is a lot more faster than drawing a ton of gizmos separately /// class MeshGizmo : IDisposable { public static readonly int vertexCountPerCube = 24; public Mesh mesh; List vertices; List indices; List colors; Material wireMaterial; Material dottedWireMaterial; Material solidMaterial; public MeshGizmo(int capacity = 0) { vertices = new List(capacity); indices = new List(capacity); colors = new List(capacity); mesh = new Mesh { indexFormat = IndexFormat.UInt32, hideFlags = HideFlags.HideAndDontSave }; #if UNITY_EDITOR wireMaterial = (Material)UnityEditor.EditorGUIUtility.LoadRequired("SceneView/HandleLines.mat"); dottedWireMaterial = (Material)UnityEditor.EditorGUIUtility.LoadRequired("SceneView/HandleDottedLines.mat"); solidMaterial = UnityEditor.HandleUtility.handleMaterial; #endif } public void Clear() { vertices.Clear(); indices.Clear(); colors.Clear(); } public void AddWireCube(Vector3 center, Vector3 size, Color color) { var halfSize = size / 2.0f; Vector3 p0 = new Vector3(halfSize.x, halfSize.y, halfSize.z); Vector3 p1 = new Vector3(-halfSize.x, halfSize.y, halfSize.z); Vector3 p2 = new Vector3(-halfSize.x, -halfSize.y, halfSize.z); Vector3 p3 = new Vector3(halfSize.x, -halfSize.y, halfSize.z); Vector3 p4 = new Vector3(halfSize.x, halfSize.y, -halfSize.z); Vector3 p5 = new Vector3(-halfSize.x, halfSize.y, -halfSize.z); Vector3 p6 = new Vector3(-halfSize.x, -halfSize.y, -halfSize.z); Vector3 p7 = new Vector3(halfSize.x, -halfSize.y, -halfSize.z); AddEdge(center + p0, center + p1); AddEdge(center + p1, center + p2); AddEdge(center + p2, center + p3); AddEdge(center + p3, center + p0); AddEdge(center + p4, center + p5); AddEdge(center + p5, center + p6); AddEdge(center + p6, center + p7); AddEdge(center + p7, center + p4); AddEdge(center + p0, center + p4); AddEdge(center + p1, center + p5); AddEdge(center + p2, center + p6); AddEdge(center + p3, center + p7); void AddEdge(Vector3 p1, Vector3 p2) { vertices.Add(p1); vertices.Add(p2); indices.Add(indices.Count); indices.Add(indices.Count); colors.Add(color); colors.Add(color); } } void DrawMesh(Matrix4x4 trs, Material mat, MeshTopology topology, CompareFunction depthTest, string gizmoName) { mesh.Clear(); mesh.SetVertices(vertices); mesh.SetColors(colors); mesh.SetIndices(indices, topology, 0); mat.SetFloat("_HandleZTest", (int)depthTest); var cmd = CommandBufferPool.Get(gizmoName ?? "Mesh Gizmo Rendering"); cmd.DrawMesh(mesh, trs, mat, 0, 0); Graphics.ExecuteCommandBuffer(cmd); } public void RenderWireframe(Matrix4x4 trs, CompareFunction depthTest = CompareFunction.LessEqual, string gizmoName = null) => DrawMesh(trs, wireMaterial, MeshTopology.Lines, depthTest, gizmoName); public void Dispose() { CoreUtils.Destroy(mesh); } } }