using System; using System.Collections.Generic; using System.Diagnostics; using UnityEngine; using UnityEngine.SceneManagement; namespace Leap.Unity.RuntimeGizmos { [ExecuteInEditMode] public class RuntimeGizmoManager : MonoBehaviour { [DebuggerBrowsable(DebuggerBrowsableState.Never)] public static event Action OnPostRenderGizmos; public static bool TryGetGizmoDrawer(out RuntimeGizmoDrawer drawer) { drawer = RuntimeGizmoManager._backDrawer; if (drawer != null) { drawer.ResetMatrixAndColorState(); return true; } return false; } public static bool TryGetGizmoDrawer(GameObject attatchedGameObject, out RuntimeGizmoDrawer drawer) { drawer = RuntimeGizmoManager._backDrawer; if (drawer != null && !RuntimeGizmoManager.areGizmosDisabled(attatchedGameObject.transform)) { drawer.ResetMatrixAndColorState(); return true; } return false; } protected virtual void OnValidate() { if (this._gizmoShader == null) { this._gizmoShader = Shader.Find("Hidden/Runtime Gizmos"); } if (new Material(this._gizmoShader) { hideFlags = HideFlags.HideAndDontSave }.passCount != 4) { UnityEngine.Debug.LogError("Shader " + this._gizmoShader + " does not have 4 passes and cannot be used as a gizmo shader."); this._gizmoShader = Shader.Find("Hidden/Runtime Gizmos"); } if (this._sphereMesh == null) { GameObject gameObject = GameObject.CreatePrimitive(PrimitiveType.Sphere); gameObject.hideFlags = HideFlags.HideAndDontSave; this._sphereMesh = gameObject.GetComponent().sharedMesh; gameObject.GetComponent().sharedMesh = null; } if (RuntimeGizmoManager._frontDrawer != null && RuntimeGizmoManager._backDrawer != null) { this.assignDrawerParams(); } } protected virtual void Reset() { this._gizmoShader = Shader.Find("Hidden/Runtime Gizmos"); } protected virtual void OnEnable() { if (!this._enabledForBuild) { base.enabled = false; return; } RuntimeGizmoManager._frontDrawer = new RuntimeGizmoDrawer(); RuntimeGizmoManager._backDrawer = new RuntimeGizmoDrawer(); RuntimeGizmoManager._frontDrawer.BeginGuard(); if (this._gizmoShader == null) { this._gizmoShader = Shader.Find("Hidden/Runtime Gizmos"); } this.generateMeshes(); this.assignDrawerParams(); Camera.onPostRender = (Camera.CameraCallback)Delegate.Remove(Camera.onPostRender, new Camera.CameraCallback(this.onPostRender)); Camera.onPostRender = (Camera.CameraCallback)Delegate.Combine(Camera.onPostRender, new Camera.CameraCallback(this.onPostRender)); } protected virtual void OnDisable() { RuntimeGizmoManager._frontDrawer = null; RuntimeGizmoManager._backDrawer = null; Camera.onPostRender = (Camera.CameraCallback)Delegate.Remove(Camera.onPostRender, new Camera.CameraCallback(this.onPostRender)); } protected virtual void Update() { SceneManager.GetActiveScene().GetRootGameObjects(this._objList); for (int i = 0; i < this._objList.Count; i++) { GameObject gameObject = this._objList[i]; gameObject.GetComponentsInChildren(false, this._gizmoList); for (int j = 0; j < this._gizmoList.Count; j++) { if (!RuntimeGizmoManager.areGizmosDisabled((this._gizmoList[j] as Component).transform)) { RuntimeGizmoManager._backDrawer.ResetMatrixAndColorState(); try { this._gizmoList[j].OnDrawRuntimeGizmos(RuntimeGizmoManager._backDrawer); } catch (Exception exception) { UnityEngine.Debug.LogException(exception); } } } } this._readyForSwap = true; } protected void onPostRender(Camera camera) { if (this._readyForSwap) { if (RuntimeGizmoManager.OnPostRenderGizmos != null) { RuntimeGizmoManager._backDrawer.ResetMatrixAndColorState(); RuntimeGizmoManager.OnPostRenderGizmos(RuntimeGizmoManager._backDrawer); } RuntimeGizmoDrawer backDrawer = RuntimeGizmoManager._backDrawer; RuntimeGizmoManager._backDrawer = RuntimeGizmoManager._frontDrawer; RuntimeGizmoManager._frontDrawer = backDrawer; RuntimeGizmoManager._frontDrawer.BeginGuard(); RuntimeGizmoManager._backDrawer.EndGuard(); this._readyForSwap = false; RuntimeGizmoManager._backDrawer.ClearAllGizmos(); } RuntimeGizmoManager._frontDrawer.DrawAllGizmosToScreen(); } protected static bool areGizmosDisabled(Transform transform) { bool result = false; do { RuntimeGizmoToggle componentInParent = transform.GetComponentInParent(); if (componentInParent == null) { break; } if (!componentInParent.enabled) { goto Block_2; } transform = transform.parent; } while (transform != null); return result; Block_2: result = true; return result; } private void assignDrawerParams() { if (this._gizmoShader != null) { RuntimeGizmoManager._frontDrawer.gizmoShader = this._gizmoShader; RuntimeGizmoManager._backDrawer.gizmoShader = this._gizmoShader; } RuntimeGizmoManager._frontDrawer.sphereMesh = this._sphereMesh; RuntimeGizmoManager._frontDrawer.cubeMesh = this._cubeMesh; RuntimeGizmoManager._frontDrawer.wireSphereMesh = this._wireSphereMesh; RuntimeGizmoManager._frontDrawer.wireCubeMesh = this._wireCubeMesh; RuntimeGizmoManager._backDrawer.sphereMesh = this._sphereMesh; RuntimeGizmoManager._backDrawer.cubeMesh = this._cubeMesh; RuntimeGizmoManager._backDrawer.wireSphereMesh = this._wireSphereMesh; RuntimeGizmoManager._backDrawer.wireCubeMesh = this._wireCubeMesh; } private void generateMeshes() { this._cubeMesh = new Mesh(); this._cubeMesh.name = "RuntimeGizmoCube"; this._cubeMesh.hideFlags = HideFlags.HideAndDontSave; List list = new List(); List list2 = new List(); Vector3[] array = new Vector3[] { Vector3.forward, Vector3.right, Vector3.up }; for (int i = 0; i < 3; i++) { this.addQuad(list, list2, array[i % 3], -array[(i + 1) % 3], array[(i + 2) % 3]); this.addQuad(list, list2, -array[i % 3], array[(i + 1) % 3], array[(i + 2) % 3]); } this._cubeMesh.SetVertices(list); this._cubeMesh.SetIndices(list2.ToArray(), MeshTopology.Quads, 0); this._cubeMesh.RecalculateNormals(); this._cubeMesh.RecalculateBounds(); this._cubeMesh.UploadMeshData(true); this._wireCubeMesh = new Mesh(); this._wireCubeMesh.name = "RuntimeWireCubeMesh"; this._wireCubeMesh.hideFlags = HideFlags.HideAndDontSave; list.Clear(); list2.Clear(); for (int j = 1; j >= -1; j -= 2) { for (int k = 1; k >= -1; k -= 2) { for (int l = 1; l >= -1; l -= 2) { list.Add(0.5f * new Vector3((float)j, (float)k, (float)l)); } } } this.addCorner(list2, 0, 1, 2, 4); this.addCorner(list2, 3, 1, 2, 7); this.addCorner(list2, 5, 1, 4, 7); this.addCorner(list2, 6, 2, 4, 7); this._wireCubeMesh.SetVertices(list); this._wireCubeMesh.SetIndices(list2.ToArray(), MeshTopology.Lines, 0); this._wireCubeMesh.RecalculateBounds(); this._wireCubeMesh.UploadMeshData(true); this._wireSphereMesh = new Mesh(); this._wireSphereMesh.name = "RuntimeWireSphereMesh"; this._wireSphereMesh.hideFlags = HideFlags.HideAndDontSave; list.Clear(); list2.Clear(); int num = 96; for (int m = 0; m < 32; m++) { float f = 6.2831855f * (float)m / 32f; float num2 = 0.5f * Mathf.Cos(f); float num3 = 0.5f * Mathf.Sin(f); for (int n = 0; n < 3; n++) { list2.Add((m * 3 + n) % num); list2.Add((m * 3 + n + 3) % num); } list.Add(new Vector3(num2, num3, 0f)); list.Add(new Vector3(0f, num2, num3)); list.Add(new Vector3(num2, 0f, num3)); } this._wireSphereMesh.SetVertices(list); this._wireSphereMesh.SetIndices(list2.ToArray(), MeshTopology.Lines, 0); this._wireSphereMesh.RecalculateBounds(); this._wireSphereMesh.UploadMeshData(true); } private void addQuad(List verts, List indexes, Vector3 normal, Vector3 axis1, Vector3 axis2) { indexes.Add(verts.Count); indexes.Add(verts.Count + 1); indexes.Add(verts.Count + 2); indexes.Add(verts.Count + 3); verts.Add(0.5f * (normal + axis1 + axis2)); verts.Add(0.5f * (normal + axis1 - axis2)); verts.Add(0.5f * (normal - axis1 - axis2)); verts.Add(0.5f * (normal - axis1 + axis2)); } private void addCorner(List indexes, int a, int b, int c, int d) { indexes.Add(a); indexes.Add(b); indexes.Add(a); indexes.Add(c); indexes.Add(a); indexes.Add(d); } public const string DEFAULT_SHADER_NAME = "Hidden/Runtime Gizmos"; public const int CIRCLE_RESOLUTION = 32; [Tooltip("Should the gizmos be visible in the game view.")] [SerializeField] protected bool _displayInGameView = true; [Tooltip("Should the gizmos be visible in a build.")] [SerializeField] protected bool _enabledForBuild = true; [Tooltip("The mesh to use for the filled sphere gizmo.")] [SerializeField] protected Mesh _sphereMesh; [Tooltip("The shader to use for rendering gizmos.")] [SerializeField] protected Shader _gizmoShader; protected Mesh _cubeMesh; protected Mesh _wireCubeMesh; protected Mesh _wireSphereMesh; protected static RuntimeGizmoDrawer _backDrawer; protected static RuntimeGizmoDrawer _frontDrawer; private bool _readyForSwap; private List _objList = new List(); private List _gizmoList = new List(); } }