Singularity/Library/PackageCache/com.unity.2d.tilemap.extras.../Editor/Tiles/RuleOverrideTile/AdvancedRuleOverrideTileEdi...
2024-05-06 11:45:45 -07:00

216 lines
9.3 KiB
C#

using UnityEngine;
using UnityEngine.Tilemaps;
using UnityEditorInternal;
using System.Collections.Generic;
namespace UnityEditor
{
/// <summary>
/// The Editor for an AdvancedRuleOverrideTileEditor.
/// </summary>
[CustomEditor(typeof(AdvancedRuleOverrideTile))]
public class AdvancedRuleOverrideTileEditor : RuleOverrideTileEditor
{
private static class Styles
{
public static readonly GUIContent defaultSprite = EditorGUIUtility.TrTextContent("Default Sprite"
, "Overrides the default Sprite for the original Rule Tile.");
public static readonly GUIContent defaultGameObject = EditorGUIUtility.TrTextContent("Default GameObject"
, "Overrides the default GameObject for the original Rule Tile.");
public static readonly GUIContent defaultCollider = EditorGUIUtility.TrTextContent("Default Collider"
, "Overrides the default Collider for the original Rule Tile.");
}
/// <summary>
/// The AdvancedRuleOverrideTile being edited.
/// </summary>
public new AdvancedRuleOverrideTile overrideTile => target as AdvancedRuleOverrideTile;
List<KeyValuePair<RuleTile.TilingRule, RuleTile.TilingRuleOutput>> m_Rules = new List<KeyValuePair<RuleTile.TilingRule, RuleTile.TilingRuleOutput>>();
private ReorderableList m_RuleList;
private int m_MissingOriginalRuleIndex;
private HashSet<int> m_UniqueIds = new HashSet<int>();
static float k_DefaultElementHeight { get { return RuleTileEditor.k_DefaultElementHeight; } }
static float k_SingleLineHeight { get { return RuleTileEditor.k_SingleLineHeight; } }
/// <summary>
/// OnEnable for the AdvancedRuleOverrideTileEditor
/// </summary>
public override void OnEnable()
{
if (m_RuleList == null)
{
m_RuleList = new ReorderableList(m_Rules, typeof(KeyValuePair<RuleTile.TilingRule, RuleTile.TilingRule>), false, true, false, false);
m_RuleList.drawHeaderCallback = DrawRulesHeader;
m_RuleList.drawElementCallback = DrawRuleElement;
m_RuleList.elementHeightCallback = GetRuleElementHeight;
}
}
/// <summary>
/// Draws the Inspector GUI for the AdvancedRuleOverrideTileEditor
/// </summary>
public override void OnInspectorGUI()
{
serializedObject.UpdateIfRequiredOrScript();
DrawTileField();
EditorGUI.BeginChangeCheck();
overrideTile.m_DefaultSprite = EditorGUILayout.ObjectField(Styles.defaultSprite, overrideTile.m_DefaultSprite, typeof(Sprite), false) as Sprite;
overrideTile.m_DefaultGameObject = EditorGUILayout.ObjectField(Styles.defaultGameObject, overrideTile.m_DefaultGameObject, typeof(GameObject), false) as GameObject;
overrideTile.m_DefaultColliderType = (Tile.ColliderType)EditorGUILayout.EnumPopup(Styles.defaultCollider, overrideTile.m_DefaultColliderType);
if (EditorGUI.EndChangeCheck())
SaveTile();
DrawCustomFields();
if (overrideTile.m_Tile)
{
ValidateRuleTile(overrideTile.m_Tile);
overrideTile.GetOverrides(m_Rules, ref m_MissingOriginalRuleIndex);
}
m_RuleList.DoLayoutList();
}
private void ValidateRuleTile(RuleTile ruleTile)
{
// Ensure that each Tiling Rule in the RuleTile has a unique ID
m_UniqueIds.Clear();
var startId = 0;
foreach (var rule in ruleTile.m_TilingRules)
{
if (m_UniqueIds.Contains(rule.m_Id))
{
do
{
rule.m_Id = startId++;
} while (m_UniqueIds.Contains(rule.m_Id));
EditorUtility.SetDirty(ruleTile);
}
m_UniqueIds.Add(rule.m_Id);
startId++;
}
}
/// <summary>
/// Draws the Header for the Rule list
/// </summary>
/// <param name="rect">Rect to draw the header in</param>
public void DrawRulesHeader(Rect rect)
{
GUI.Label(rect, "Tiling Rules", EditorStyles.label);
}
/// <summary>
/// Draws the Rule element for the Rule list
/// </summary>
/// <param name="rect">Rect to draw the Rule Element in</param>
/// <param name="index">Index of the Rule Element to draw</param>
/// <param name="active">Whether the Rule Element is active</param>
/// <param name="focused">Whether the Rule Element is focused</param>
public void DrawRuleElement(Rect rect, int index, bool active, bool focused)
{
RuleTile.TilingRule originalRule = m_Rules[index].Key;
if (originalRule == null)
return;
RuleTile.TilingRuleOutput overrideRule = m_Rules[index].Value;
bool isMissing = index >= m_MissingOriginalRuleIndex;
DrawToggleInternal(new Rect(rect.xMin, rect.yMin, 16, rect.height));
DrawRuleInternal(new Rect(rect.xMin + 16, rect.yMin, rect.width - 16, rect.height));
void DrawToggleInternal(Rect r)
{
EditorGUI.BeginChangeCheck();
bool enabled = EditorGUI.Toggle(new Rect(r.xMin, r.yMin, r.width, k_SingleLineHeight), overrideRule != null);
if (EditorGUI.EndChangeCheck())
{
if (enabled)
overrideTile[originalRule] = originalRule;
else
overrideTile[originalRule] = null;
SaveTile();
}
}
void DrawRuleInternal(Rect r)
{
EditorGUI.BeginChangeCheck();
DrawRule(r, overrideRule ?? originalRule, overrideRule != null, originalRule, isMissing);
if (EditorGUI.EndChangeCheck())
SaveTile();
}
}
/// <summary>
/// Draw a Rule Override for the AdvancedRuleOverrideTileEditor
/// </summary>
/// <param name="rect">Rect to draw the Rule in</param>
/// <param name="rule">The Rule Override to draw</param>
/// <param name="isOverride">Whether the original Rule is being overridden</param>
/// <param name="originalRule">Original Rule to override</param>
/// <param name="isMissing">Whether the original Rule is missing</param>
public void DrawRule(Rect rect, RuleTile.TilingRuleOutput rule, bool isOverride, RuleTile.TilingRule originalRule, bool isMissing)
{
if (isMissing)
{
EditorGUI.HelpBox(new Rect(rect.xMin, rect.yMin, rect.width, 16), "Original Tiling Rule missing", MessageType.Warning);
rect.yMin += 16;
}
using (new EditorGUI.DisabledScope(!isOverride))
{
float yPos = rect.yMin + 2f;
float height = rect.height - k_PaddingBetweenRules;
float matrixWidth = k_DefaultElementHeight;
BoundsInt ruleBounds = originalRule.GetBounds();
BoundsInt ruleGuiBounds = ruleTileEditor.GetRuleGUIBounds(ruleBounds, originalRule);
Vector2 matrixSize = ruleTileEditor.GetMatrixSize(ruleGuiBounds);
Vector2 matrixSizeRate = matrixSize / Mathf.Max(matrixSize.x, matrixSize.y);
Vector2 matrixRectSize = new Vector2(matrixWidth * matrixSizeRate.x, k_DefaultElementHeight * matrixSizeRate.y);
Vector2 matrixRectPosition = new Vector2(rect.xMax - matrixWidth * 2f - 10f, yPos);
matrixRectPosition.x += (matrixWidth - matrixRectSize.x) * 0.5f;
matrixRectPosition.y += (k_DefaultElementHeight - matrixRectSize.y) * 0.5f;
Rect inspectorRect = new Rect(rect.xMin, yPos, rect.width - matrixWidth * 2f - 20f, height);
Rect matrixRect = new Rect(matrixRectPosition, matrixRectSize);
Rect spriteRect = new Rect(rect.xMax - matrixWidth - 5f, yPos, matrixWidth, k_DefaultElementHeight);
ruleTileEditor.RuleInspectorOnGUI(inspectorRect, rule);
ruleTileEditor.SpriteOnGUI(spriteRect, rule);
if (!isMissing)
using (new EditorGUI.DisabledScope(true))
ruleTileEditor.RuleMatrixOnGUI(overrideTile.m_InstanceTile, matrixRect, ruleGuiBounds, originalRule);
}
}
/// <summary>
/// Returns the height for an indexed Rule Element
/// </summary>
/// <param name="index">Index of the Rule Element</param>
/// <returns>Height of the indexed Rule Element</returns>
public float GetRuleElementHeight(int index)
{
var originalRule = m_Rules[index].Key;
var overrideRule = m_Rules[index].Value;
float height = overrideRule != null ? ruleTileEditor.GetElementHeight(overrideRule) : ruleTileEditor.GetElementHeight(originalRule);
bool isMissing = index >= m_MissingOriginalRuleIndex;
if (isMissing)
height += 16;
return height;
}
}
}