123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430 |
- using UnityEngine;
- using UnityEngine.Tilemaps;
- using UnityEditorInternal;
- using System.Collections.Generic;
-
- namespace UnityEditor
- {
- /// <summary>
- /// The Editor for a RuleOverrideTileEditor.
- /// </summary>
- [CustomEditor(typeof(RuleOverrideTile))]
- public class RuleOverrideTileEditor : Editor
- {
- private static class Styles
- {
- public static readonly GUIContent overrideTile = EditorGUIUtility.TrTextContent("Tile"
- , "The Rule Tile to override.");
- }
-
- /// <summary>
- /// The RuleOverrideTile being edited
- /// </summary>
- public RuleOverrideTile overrideTile => target as RuleOverrideTile;
- /// <summary>
- /// The RuleTileEditor for the overridden instance of the RuleTile
- /// </summary>
- public RuleTileEditor ruleTileEditor
- {
- get
- {
- if (m_RuleTileEditorTarget != overrideTile.m_Tile)
- {
- DestroyImmediate(m_RuleTileEditor);
- m_RuleTileEditor = Editor.CreateEditor(overrideTile.m_InstanceTile) as RuleTileEditor;
- m_RuleTileEditorTarget = overrideTile.m_Tile;
- }
- return m_RuleTileEditor;
- }
- }
-
- RuleTileEditor m_RuleTileEditor;
- RuleTile m_RuleTileEditorTarget;
-
- /// <summary>
- /// List of Sprites and overriding Sprites
- /// </summary>
- public List<KeyValuePair<Sprite, Sprite>> m_Sprites = new List<KeyValuePair<Sprite, Sprite>>();
- /// <summary>
- /// List of GameObjects and overriding GameObjects
- /// </summary>
- public List<KeyValuePair<GameObject, GameObject>> m_GameObjects = new List<KeyValuePair<GameObject, GameObject>>();
- private ReorderableList m_SpriteList;
- private ReorderableList m_GameObjectList;
- private int m_MissingOriginalSpriteIndex;
- private int m_MissingOriginalGameObjectIndex;
-
- /// <summary>
- /// Height for a Sprite Element
- /// </summary>
- public static float k_SpriteElementHeight = 48;
- /// <summary>
- /// Height for a GameObject Element
- /// </summary>
- public static float k_GameObjectElementHeight = 16;
- /// <summary>
- /// Padding between Rule Elements
- /// </summary>
- public static float k_PaddingBetweenRules = 4;
-
- /// <summary>
- /// OnEnable for the RuleOverrideTileEditor
- /// </summary>
- public virtual void OnEnable()
- {
- if (m_SpriteList == null)
- {
- m_SpriteList = new ReorderableList(m_Sprites, typeof(KeyValuePair<Sprite, Sprite>), false, true, false, false);
- m_SpriteList.drawHeaderCallback = DrawSpriteListHeader;
- m_SpriteList.drawElementCallback = DrawSpriteElement;
- m_SpriteList.elementHeightCallback = GetSpriteElementHeight;
- }
- if (m_GameObjectList == null)
- {
- m_GameObjectList = new ReorderableList(m_GameObjects, typeof(KeyValuePair<Sprite, Sprite>), false, true, false, false);
- m_GameObjectList.drawHeaderCallback = DrawGameObjectListHeader;
- m_GameObjectList.drawElementCallback = DrawGameObjectElement;
- m_GameObjectList.elementHeightCallback = GetGameObjectElementHeight;
- }
- }
-
- /// <summary>
- /// OnDisable for the RuleOverrideTileEditor
- /// </summary>
- public virtual void OnDisable()
- {
- DestroyImmediate(ruleTileEditor);
- m_RuleTileEditorTarget = null;
- }
-
- /// <summary>
- /// Draws the Inspector GUI for the RuleOverrideTileEditor
- /// </summary>
- public override void OnInspectorGUI()
- {
- serializedObject.UpdateIfRequiredOrScript();
-
- DrawTileField();
- DrawCustomFields();
-
- overrideTile.GetOverrides(m_Sprites, ref m_MissingOriginalSpriteIndex);
- overrideTile.GetOverrides(m_GameObjects, ref m_MissingOriginalGameObjectIndex);
-
- EditorGUI.BeginChangeCheck();
- m_SpriteList.DoLayoutList();
- if (EditorGUI.EndChangeCheck())
- {
- overrideTile.ApplyOverrides(m_Sprites);
- SaveTile();
- }
-
- EditorGUI.BeginChangeCheck();
- m_GameObjectList.DoLayoutList();
- if (EditorGUI.EndChangeCheck())
- {
- overrideTile.ApplyOverrides(m_GameObjects);
- SaveTile();
- }
- }
-
- /// <summary>
- /// Draws the header for the Sprite list
- /// </summary>
- /// <param name="rect">GUI Rect to draw the header at</param>
- public void DrawSpriteListHeader(Rect rect)
- {
- float xMax = rect.xMax;
- rect.xMax = rect.xMax / 2.0f;
- GUI.Label(rect, "Original Sprite", EditorStyles.label);
- rect.xMin = rect.xMax;
- rect.xMax = xMax;
- GUI.Label(rect, "Override Sprite", EditorStyles.label);
- }
-
- /// <summary>
- /// Draws the header for the GameObject list
- /// </summary>
- /// <param name="rect">GUI Rect to draw the header at</param>
- public void DrawGameObjectListHeader(Rect rect)
- {
- float xMax = rect.xMax;
- rect.xMax = rect.xMax / 2.0f;
- GUI.Label(rect, "Original GameObject", EditorStyles.label);
- rect.xMin = rect.xMax;
- rect.xMax = xMax;
- GUI.Label(rect, "Override GameObject", EditorStyles.label);
- }
-
- /// <summary>
- /// Gets the GUI element height for a Sprite element with the given index
- /// </summary>
- /// <param name="index">Index of the Sprite element</param>
- /// <returns>GUI element height for the Sprite element</returns>
- public float GetSpriteElementHeight(int index)
- {
- float height = k_SpriteElementHeight + k_PaddingBetweenRules;
-
- bool isMissing = index >= m_MissingOriginalSpriteIndex;
- if (isMissing)
- height += 16;
-
- return height;
- }
-
- /// <summary>
- /// Gets the GUI element height for a GameObject element with the given index
- /// </summary>
- /// <param name="index">Index of the GameObject element</param>
- /// <returns>GUI element height for the GameObject element</returns>
- public float GetGameObjectElementHeight(int index)
- {
- float height = k_GameObjectElementHeight + k_PaddingBetweenRules;
-
- bool isMissing = index >= m_MissingOriginalGameObjectIndex;
- if (isMissing)
- height += 16;
-
- return height;
- }
-
- /// <summary>
- /// Draws the Sprite element for the RuleOverride list
- /// </summary>
- /// <param name="rect">Rect to draw the Sprite Element in</param>
- /// <param name="index">Index of the Sprite Element to draw</param>
- /// <param name="active">Whether the Sprite Element is active</param>
- /// <param name="focused">Whether the Sprite Element is focused</param>
- public void DrawSpriteElement(Rect rect, int index, bool active, bool focused)
- {
- bool isMissing = index >= m_MissingOriginalSpriteIndex;
- if (isMissing)
- {
- EditorGUI.HelpBox(new Rect(rect.xMin, rect.yMin, rect.width, 16), "Original Sprite missing", MessageType.Warning);
- rect.yMin += 16;
- }
-
- Sprite originalSprite = m_Sprites[index].Key;
- Sprite overrideSprite = m_Sprites[index].Value;
-
- rect.y += 2;
- rect.height -= k_PaddingBetweenRules;
-
- rect.xMax = rect.xMax / 2.0f;
- using (new EditorGUI.DisabledScope(true))
- EditorGUI.ObjectField(new Rect(rect.xMin, rect.yMin, rect.height, rect.height), originalSprite, typeof(Sprite), false);
- rect.xMin = rect.xMax;
- rect.xMax *= 2.0f;
-
- EditorGUI.BeginChangeCheck();
- overrideSprite = EditorGUI.ObjectField(new Rect(rect.xMin, rect.yMin, rect.height, rect.height), overrideSprite, typeof(Sprite), false) as Sprite;
- if (EditorGUI.EndChangeCheck())
- m_Sprites[index] = new KeyValuePair<Sprite, Sprite>(originalSprite, overrideSprite);
- }
-
- /// <summary>
- /// Draws the GameObject element for the RuleOverride list
- /// </summary>
- /// <param name="rect">Rect to draw the GameObject Element in</param>
- /// <param name="index">Index of the GameObject Element to draw</param>
- /// <param name="active">Whether the GameObject Element is active</param>
- /// <param name="focused">Whether the GameObject Element is focused</param>
- public void DrawGameObjectElement(Rect rect, int index, bool active, bool focused)
- {
- bool isMissing = index >= m_MissingOriginalGameObjectIndex;
- if (isMissing)
- {
- EditorGUI.HelpBox(new Rect(rect.xMin, rect.yMin, rect.width, 16), "Original GameObject missing", MessageType.Warning);
- rect.yMin += 16;
- }
-
- GameObject originalGameObject = m_GameObjects[index].Key;
- GameObject overrideGameObject = m_GameObjects[index].Value;
-
- rect.y += 2;
- rect.height -= k_PaddingBetweenRules;
-
- rect.xMax = rect.xMax / 2.0f;
- using (new EditorGUI.DisabledScope(true))
- EditorGUI.ObjectField(new Rect(rect.xMin, rect.yMin, rect.width, rect.height), originalGameObject, typeof(GameObject), false);
- rect.xMin = rect.xMax;
- rect.xMax *= 2.0f;
-
- EditorGUI.BeginChangeCheck();
- overrideGameObject = EditorGUI.ObjectField(new Rect(rect.xMin, rect.yMin, rect.width, rect.height), overrideGameObject, typeof(GameObject), false) as GameObject;
- if (EditorGUI.EndChangeCheck())
- m_GameObjects[index] = new KeyValuePair<GameObject, GameObject>(originalGameObject, overrideGameObject);
- }
-
- /// <summary>
- /// Draws a field for the RuleTile be overridden
- /// </summary>
- public void DrawTileField()
- {
- EditorGUI.BeginChangeCheck();
- RuleTile tile = EditorGUILayout.ObjectField(Styles.overrideTile, overrideTile.m_Tile, typeof(RuleTile), false) as RuleTile;
- if (EditorGUI.EndChangeCheck())
- {
- if (!LoopCheck(tile))
- {
- overrideTile.m_Tile = tile;
- SaveTile();
- }
- else
- {
- Debug.LogWarning("Circular tile reference");
- }
- }
-
- bool LoopCheck(RuleTile checkTile)
- {
- if (!overrideTile.m_InstanceTile)
- return false;
-
- HashSet<RuleTile> renferenceTils = new HashSet<RuleTile>();
- Add(overrideTile.m_InstanceTile);
-
- return renferenceTils.Contains(checkTile);
-
- void Add(RuleTile ruleTile)
- {
- if (renferenceTils.Contains(ruleTile))
- return;
-
- renferenceTils.Add(ruleTile);
-
- var overrideTiles = RuleTileEditor.FindAffectedOverrideTiles(ruleTile);
-
- foreach (var overrideTile in overrideTiles)
- Add(overrideTile.m_InstanceTile);
- }
- }
- }
-
- /// <summary>
- /// Draw editor fields for custom properties for the RuleOverrideTile
- /// </summary>
- public void DrawCustomFields()
- {
- if (ruleTileEditor)
- {
- ruleTileEditor.target.hideFlags = HideFlags.None;
- ruleTileEditor.DrawCustomFields(true);
- ruleTileEditor.target.hideFlags = HideFlags.NotEditable;
- }
- }
-
- private void SaveInstanceTileAsset()
- {
- bool assetChanged = false;
-
- if (overrideTile.m_InstanceTile)
- {
- if (!overrideTile.m_Tile || overrideTile.m_InstanceTile.GetType() != overrideTile.m_Tile.GetType())
- {
- DestroyImmediate(overrideTile.m_InstanceTile, true);
- overrideTile.m_InstanceTile = null;
- assetChanged = true;
- }
- }
- if (!overrideTile.m_InstanceTile)
- {
- if (overrideTile.m_Tile)
- {
- var t = overrideTile.m_Tile.GetType();
- RuleTile instanceTile = ScriptableObject.CreateInstance(t) as RuleTile;
- instanceTile.hideFlags = HideFlags.NotEditable;
- AssetDatabase.AddObjectToAsset(instanceTile, overrideTile);
- overrideTile.m_InstanceTile = instanceTile;
- assetChanged = true;
- }
- }
-
- if (overrideTile.m_InstanceTile)
- {
- string instanceTileName = overrideTile.m_Tile.name + " (Override)";
- if (overrideTile.m_InstanceTile.name != instanceTileName)
- {
- overrideTile.m_InstanceTile.name = instanceTileName;
- assetChanged = true;
- }
- }
-
- if (assetChanged)
- {
- EditorUtility.SetDirty(overrideTile.m_InstanceTile);
- AssetDatabase.SaveAssetIfDirty(overrideTile.m_InstanceTile);
- }
- }
-
- /// <summary>
- /// Saves any changes to the RuleOverrideTile
- /// </summary>
- public void SaveTile()
- {
- EditorUtility.SetDirty(target);
- SceneView.RepaintAll();
-
- SaveInstanceTileAsset();
-
- if (overrideTile.m_InstanceTile)
- {
- overrideTile.Override();
- RuleTileEditor.UpdateAffectedOverrideTiles(overrideTile.m_InstanceTile);
- }
-
- if (ruleTileEditor && ruleTileEditor.m_PreviewTilemaps != null)
- {
- foreach (var tilemap in ruleTileEditor.m_PreviewTilemaps)
- tilemap.RefreshAllTiles();
- }
- }
-
- /// <summary>
- /// Renders a static preview Texture2D for a RuleOverrideTile asset
- /// </summary>
- /// <param name="assetPath">Asset path of the RuleOverrideTile</param>
- /// <param name="subAssets">Arrays of assets from the given Asset path</param>
- /// <param name="width">Width of the static preview</param>
- /// <param name="height">Height of the static preview </param>
- /// <returns>Texture2D containing static preview for the RuleOverrideTile asset</returns>
- public override Texture2D RenderStaticPreview(string assetPath, Object[] subAssets, int width, int height)
- {
- if (ruleTileEditor)
- return ruleTileEditor.RenderStaticPreview(assetPath, subAssets, width, height);
-
- return base.RenderStaticPreview(assetPath, subAssets, width, height);
- }
-
- /// <summary>
- /// Whether the RuleOverrideTile has a preview GUI
- /// </summary>
- /// <returns>True if RuleOverrideTile has a preview GUI. False if not.</returns>
- public override bool HasPreviewGUI()
- {
- if (ruleTileEditor)
- return ruleTileEditor.HasPreviewGUI();
-
- return false;
- }
-
- /// <summary>
- /// Updates preview settings for the RuleOverrideTile.
- /// </summary>
- public override void OnPreviewSettings()
- {
- if (ruleTileEditor)
- ruleTileEditor.OnPreviewSettings();
- }
-
- /// <summary>
- /// Draws the preview GUI for the RuleTile
- /// </summary>
- /// <param name="rect">Rect to draw the preview GUI</param>
- /// <param name="background">The GUIStyle of the background for the preview</param>
- public override void OnPreviewGUI(Rect rect, GUIStyle background)
- {
- if (ruleTileEditor)
- ruleTileEditor.OnPreviewGUI(rect, background);
- }
- }
- }
|