Rasagar/Library/PackageCache/com.unity.2d.tilemap/Editor/SceneViewGridManager.cs
2024-08-26 23:07:20 +03:00

235 lines
8.5 KiB
C#

using System.Collections.Generic;
using UnityEngine;
namespace UnityEditor.Tilemaps
{
/// <summary> This class is in charge of handling Grid component based grid in the scene view (rendering, snapping).
/// It will hide global scene view grid when it has something to render</summary>
internal class SceneViewGridManager : ScriptableSingleton<SceneViewGridManager>
{
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);
private static Mesh s_GridProxyMesh;
private static Material s_GridProxyMaterial;
private static int s_LastGridProxyHash;
[SerializeField]
private GridLayout m_ActiveGridProxy;
private Dictionary<SceneView, bool> m_SceneViewShowGridMap;
private bool m_RegisteredEventHandlers;
private bool active { get { return m_ActiveGridProxy != null; } }
internal GridLayout activeGridProxy { get { return m_ActiveGridProxy; } }
private UnityType m_GridType;
[InitializeOnLoadMethod]
private static void Initialize()
{
instance.RegisterEventHandlers();
}
private void OnEnable()
{
m_SceneViewShowGridMap = new Dictionary<SceneView, bool>();
RegisterEventHandlers();
}
private void RegisterEventHandlers()
{
if (m_RegisteredEventHandlers)
return;
SceneView.duringSceneGui += OnSceneGuiDelegate;
Selection.selectionChanged += UpdateCache;
EditorApplication.hierarchyChanged += UpdateCache;
UnityEditor.EditorTools.ToolManager.activeToolChanged += ActiveToolChanged;
EditorApplication.quitting += EditorQuitting;
GridPaintingState.brushChanged += OnBrushChanged;
GridPaintingState.scenePaintTargetChanged += OnScenePaintTargetChanged;
GridSnapping.snapPosition = OnSnapPosition;
GridSnapping.activeFunc = GetActive;
m_GridType = UnityType.FindTypeByName("Grid");
m_RegisteredEventHandlers = true;
}
private void OnBrushChanged(GridBrushBase brush)
{
UpdateCache();
}
private void ActiveToolChanged()
{
UpdateCache();
}
private void OnScenePaintTargetChanged(GameObject scenePaintTarget)
{
UpdateCache();
}
private void OnDisable()
{
FlushCachedGridProxy();
RestoreSceneViewShowGrid();
SceneView.duringSceneGui -= OnSceneGuiDelegate;
Selection.selectionChanged -= UpdateCache;
EditorApplication.hierarchyChanged -= UpdateCache;
EditorApplication.quitting -= EditorQuitting;
UnityEditor.EditorTools.ToolManager.activeToolChanged -= ActiveToolChanged;
GridPaintingState.brushChanged -= OnBrushChanged;
GridPaintingState.scenePaintTargetChanged -= OnScenePaintTargetChanged;
GridSnapping.snapPosition = null;
GridSnapping.activeFunc = null;
m_RegisteredEventHandlers = false;
}
private void UpdateCache()
{
GridLayout gridProxy;
if (PaintableGrid.InGridEditMode() || GridSelectionTool.IsActive())
gridProxy = GridPaintingState.scenePaintTarget != null ? GridPaintingState.scenePaintTarget.GetComponentInParent<GridLayout>() : null;
else
gridProxy = Selection.activeGameObject != null ? Selection.activeGameObject.GetComponentInParent<GridLayout>() : null;
if (gridProxy != m_ActiveGridProxy)
{
if (m_ActiveGridProxy == null)
{
// Disable SceneView grid if there is now a GridProxy. Store user settings to be restored.
StoreSceneViewShowGrid(false);
}
else if (gridProxy == null)
{
RestoreSceneViewShowGrid();
}
m_ActiveGridProxy = gridProxy;
FlushCachedGridProxy();
SceneView.RepaintAll();
}
}
private void EditorQuitting()
{
if (NeedsRestoreSceneViewShowGrid())
{
RestoreSceneViewShowGrid();
// SceneView.showGrid is part of default window preferences
WindowLayout.SaveDefaultWindowPreferences();
}
}
internal bool IsGridAnnotationEnabled()
{
var annotations = AnnotationUtility.GetAnnotations();
foreach (var annotation in annotations)
{
if (annotation.classID == m_GridType.persistentTypeID)
{
return annotation.gizmoEnabled > 0;
}
}
return false;
}
private void OnSceneGuiDelegate(SceneView sceneView)
{
if (active && sceneView.drawGizmos && IsGridAnnotationEnabled())
DrawGrid(activeGridProxy);
}
private static int GenerateHash(GridLayout layout, Color color)
{
int hash = 0x7ed55d16;
hash ^= layout.cellSize.GetHashCode();
hash ^= layout.cellLayout.GetHashCode() << 23;
hash ^= (layout.cellGap.GetHashCode() << 4) + 0x165667b1;
hash ^= layout.cellSwizzle.GetHashCode() << 7;
hash ^= color.GetHashCode();
return hash;
}
private static void DrawGrid(GridLayout gridLayout)
{
int gridHash = GenerateHash(gridLayout, sceneViewGridComponentGizmo.Color);
if (s_LastGridProxyHash != gridHash)
{
FlushCachedGridProxy();
s_LastGridProxyHash = gridHash;
}
GridEditorUtility.DrawGridGizmo(gridLayout, gridLayout.transform, sceneViewGridComponentGizmo.Color, ref s_GridProxyMesh, ref s_GridProxyMaterial);
}
private bool NeedsRestoreSceneViewShowGrid()
{
return m_SceneViewShowGridMap.Count > 0;
}
private void StoreSceneViewShowGrid(bool value)
{
m_SceneViewShowGridMap.Clear();
foreach (SceneView sceneView in SceneView.sceneViews)
{
m_SceneViewShowGridMap.Add(sceneView, sceneView.showGrid);
sceneView.showGrid = value;
}
}
private void RestoreSceneViewShowGrid()
{
foreach (var item in m_SceneViewShowGridMap)
{
var sceneView = item.Key;
if (sceneView != null)
sceneView.showGrid = item.Value;
}
m_SceneViewShowGridMap.Clear();
}
private bool GetActive()
{
return active;
}
internal Vector3 OnSnapPosition(Vector3 position)
{
Vector3 result = position;
if (active && (EditorSnapSettings.hotkeyActive || EditorSnapSettings.gridSnapActive))
{
// This will automatically prefer the Grid
Vector3 local = activeGridProxy.WorldToLocal(position);
Vector3 interpolatedCell = activeGridProxy.LocalToCellInterpolated(local);
Vector3 inverse = Vector3.one;
inverse.x = Mathf.Approximately(EditorSnapSettings.move.x, 0.0f) ? 1.0f : 1.0f / EditorSnapSettings.move.x;
inverse.y = Mathf.Approximately(EditorSnapSettings.move.y, 0.0f) ? 1.0f : 1.0f / EditorSnapSettings.move.y;
inverse.z = Mathf.Approximately(EditorSnapSettings.move.z, 0.0f) ? 1.0f : 1.0f / EditorSnapSettings.move.z;
Vector3 roundedCell = new Vector3(
Mathf.Round(inverse.x * interpolatedCell.x) / inverse.x,
Mathf.Round(inverse.y * interpolatedCell.y) / inverse.y,
Mathf.Round(inverse.z * interpolatedCell.z) / inverse.z
);
local = activeGridProxy.CellToLocalInterpolated(roundedCell);
result = activeGridProxy.LocalToWorld(local);
}
return result;
}
internal static void FlushCachedGridProxy()
{
if (s_GridProxyMesh == null)
return;
DestroyImmediate(s_GridProxyMesh);
s_GridProxyMesh = null;
s_GridProxyMaterial = null;
}
}
}