Geen omschrijving
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SceneViewGridManager.cs 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. namespace UnityEditor.Tilemaps
  4. {
  5. /// <summary> This class is in charge of handling Grid component based grid in the scene view (rendering, snapping).
  6. /// It will hide global scene view grid when it has something to render</summary>
  7. internal class SceneViewGridManager : ScriptableSingleton<SceneViewGridManager>
  8. {
  9. internal static readonly PrefColor sceneViewGridComponentGizmo = new PrefColor("Scene/Grid Component", 255.0f / 255.0f, 255.0f / 255.0f, 255.0f / 255.0f, 25.5f / 255.0f);
  10. private static Mesh s_GridProxyMesh;
  11. private static Material s_GridProxyMaterial;
  12. private static int s_LastGridProxyHash;
  13. [SerializeField]
  14. private GridLayout m_ActiveGridProxy;
  15. private Dictionary<SceneView, bool> m_SceneViewShowGridMap;
  16. private bool m_RegisteredEventHandlers;
  17. private bool active { get { return m_ActiveGridProxy != null; } }
  18. internal GridLayout activeGridProxy { get { return m_ActiveGridProxy; } }
  19. private UnityType m_GridType;
  20. [InitializeOnLoadMethod]
  21. private static void Initialize()
  22. {
  23. instance.RegisterEventHandlers();
  24. }
  25. private void OnEnable()
  26. {
  27. m_SceneViewShowGridMap = new Dictionary<SceneView, bool>();
  28. RegisterEventHandlers();
  29. }
  30. private void RegisterEventHandlers()
  31. {
  32. if (m_RegisteredEventHandlers)
  33. return;
  34. SceneView.duringSceneGui += OnSceneGuiDelegate;
  35. Selection.selectionChanged += UpdateCache;
  36. EditorApplication.hierarchyChanged += UpdateCache;
  37. UnityEditor.EditorTools.ToolManager.activeToolChanged += ActiveToolChanged;
  38. EditorApplication.quitting += EditorQuitting;
  39. GridPaintingState.brushChanged += OnBrushChanged;
  40. GridPaintingState.scenePaintTargetChanged += OnScenePaintTargetChanged;
  41. GridSnapping.snapPosition = OnSnapPosition;
  42. GridSnapping.activeFunc = GetActive;
  43. m_GridType = UnityType.FindTypeByName("Grid");
  44. m_RegisteredEventHandlers = true;
  45. }
  46. private void OnBrushChanged(GridBrushBase brush)
  47. {
  48. UpdateCache();
  49. }
  50. private void ActiveToolChanged()
  51. {
  52. UpdateCache();
  53. }
  54. private void OnScenePaintTargetChanged(GameObject scenePaintTarget)
  55. {
  56. UpdateCache();
  57. }
  58. private void OnDisable()
  59. {
  60. FlushCachedGridProxy();
  61. RestoreSceneViewShowGrid();
  62. SceneView.duringSceneGui -= OnSceneGuiDelegate;
  63. Selection.selectionChanged -= UpdateCache;
  64. EditorApplication.hierarchyChanged -= UpdateCache;
  65. EditorApplication.quitting -= EditorQuitting;
  66. UnityEditor.EditorTools.ToolManager.activeToolChanged -= ActiveToolChanged;
  67. GridPaintingState.brushChanged -= OnBrushChanged;
  68. GridPaintingState.scenePaintTargetChanged -= OnScenePaintTargetChanged;
  69. GridSnapping.snapPosition = null;
  70. GridSnapping.activeFunc = null;
  71. m_RegisteredEventHandlers = false;
  72. }
  73. private void UpdateCache()
  74. {
  75. GridLayout gridProxy;
  76. if (PaintableGrid.InGridEditMode() || GridSelectionTool.IsActive())
  77. gridProxy = GridPaintingState.scenePaintTarget != null ? GridPaintingState.scenePaintTarget.GetComponentInParent<GridLayout>() : null;
  78. else
  79. gridProxy = Selection.activeGameObject != null ? Selection.activeGameObject.GetComponentInParent<GridLayout>() : null;
  80. if (gridProxy != m_ActiveGridProxy)
  81. {
  82. if (m_ActiveGridProxy == null)
  83. {
  84. // Disable SceneView grid if there is now a GridProxy. Store user settings to be restored.
  85. StoreSceneViewShowGrid(false);
  86. }
  87. else if (gridProxy == null)
  88. {
  89. RestoreSceneViewShowGrid();
  90. }
  91. m_ActiveGridProxy = gridProxy;
  92. FlushCachedGridProxy();
  93. SceneView.RepaintAll();
  94. }
  95. }
  96. private void EditorQuitting()
  97. {
  98. if (NeedsRestoreSceneViewShowGrid())
  99. {
  100. RestoreSceneViewShowGrid();
  101. // SceneView.showGrid is part of default window preferences
  102. WindowLayout.SaveDefaultWindowPreferences();
  103. }
  104. }
  105. internal bool IsGridAnnotationEnabled()
  106. {
  107. var annotations = AnnotationUtility.GetAnnotations();
  108. foreach (var annotation in annotations)
  109. {
  110. if (annotation.classID == m_GridType.persistentTypeID)
  111. {
  112. return annotation.gizmoEnabled > 0;
  113. }
  114. }
  115. return false;
  116. }
  117. private void OnSceneGuiDelegate(SceneView sceneView)
  118. {
  119. if (active && sceneView.drawGizmos && IsGridAnnotationEnabled())
  120. DrawGrid(activeGridProxy);
  121. }
  122. private static int GenerateHash(GridLayout layout, Color color)
  123. {
  124. int hash = 0x7ed55d16;
  125. hash ^= layout.cellSize.GetHashCode();
  126. hash ^= layout.cellLayout.GetHashCode() << 23;
  127. hash ^= (layout.cellGap.GetHashCode() << 4) + 0x165667b1;
  128. hash ^= layout.cellSwizzle.GetHashCode() << 7;
  129. hash ^= color.GetHashCode();
  130. return hash;
  131. }
  132. private static void DrawGrid(GridLayout gridLayout)
  133. {
  134. int gridHash = GenerateHash(gridLayout, sceneViewGridComponentGizmo.Color);
  135. if (s_LastGridProxyHash != gridHash)
  136. {
  137. FlushCachedGridProxy();
  138. s_LastGridProxyHash = gridHash;
  139. }
  140. GridEditorUtility.DrawGridGizmo(gridLayout, gridLayout.transform, sceneViewGridComponentGizmo.Color, ref s_GridProxyMesh, ref s_GridProxyMaterial);
  141. }
  142. private bool NeedsRestoreSceneViewShowGrid()
  143. {
  144. return m_SceneViewShowGridMap.Count > 0;
  145. }
  146. private void StoreSceneViewShowGrid(bool value)
  147. {
  148. m_SceneViewShowGridMap.Clear();
  149. foreach (SceneView sceneView in SceneView.sceneViews)
  150. {
  151. m_SceneViewShowGridMap.Add(sceneView, sceneView.showGrid);
  152. sceneView.showGrid = value;
  153. }
  154. }
  155. private void RestoreSceneViewShowGrid()
  156. {
  157. foreach (var item in m_SceneViewShowGridMap)
  158. {
  159. var sceneView = item.Key;
  160. if (sceneView != null)
  161. sceneView.showGrid = item.Value;
  162. }
  163. m_SceneViewShowGridMap.Clear();
  164. }
  165. private bool GetActive()
  166. {
  167. return active;
  168. }
  169. internal Vector3 OnSnapPosition(Vector3 position)
  170. {
  171. Vector3 result = position;
  172. if (active && (EditorSnapSettings.hotkeyActive || EditorSnapSettings.gridSnapActive))
  173. {
  174. // This will automatically prefer the Grid
  175. Vector3 local = activeGridProxy.WorldToLocal(position);
  176. Vector3 interpolatedCell = activeGridProxy.LocalToCellInterpolated(local);
  177. Vector3 inverse = Vector3.one;
  178. inverse.x = Mathf.Approximately(EditorSnapSettings.move.x, 0.0f) ? 1.0f : 1.0f / EditorSnapSettings.move.x;
  179. inverse.y = Mathf.Approximately(EditorSnapSettings.move.y, 0.0f) ? 1.0f : 1.0f / EditorSnapSettings.move.y;
  180. inverse.z = Mathf.Approximately(EditorSnapSettings.move.z, 0.0f) ? 1.0f : 1.0f / EditorSnapSettings.move.z;
  181. Vector3 roundedCell = new Vector3(
  182. Mathf.Round(inverse.x * interpolatedCell.x) / inverse.x,
  183. Mathf.Round(inverse.y * interpolatedCell.y) / inverse.y,
  184. Mathf.Round(inverse.z * interpolatedCell.z) / inverse.z
  185. );
  186. local = activeGridProxy.CellToLocalInterpolated(roundedCell);
  187. result = activeGridProxy.LocalToWorld(local);
  188. }
  189. return result;
  190. }
  191. internal static void FlushCachedGridProxy()
  192. {
  193. if (s_GridProxyMesh == null)
  194. return;
  195. DestroyImmediate(s_GridProxyMesh);
  196. s_GridProxyMesh = null;
  197. s_GridProxyMaterial = null;
  198. }
  199. }
  200. }