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