// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2023 Kybernetik // #if UNITY_EDITOR #pragma warning disable CS0649 // Field is never assigned to, and will always have its default value. using System; using UnityEditor; using UnityEngine; namespace Animancer.Editor.Tools { /// [Editor-Only] [Pro-Only] /// A for modifying detauls. /// /// /// Documentation: Modify Sprites /// /// https://kybernetik.com.au/animancer/api/Animancer.Editor.Tools/ModifySpritesTool /// [Serializable] public class ModifySpritesTool : SpriteModifierTool { /************************************************************************************************************************/ [SerializeField] private OffsetRectMode _RectMode; [SerializeField] private Rect _RectOffset; [SerializeField] private bool _SetPivot; [SerializeField] private Vector2 _Pivot; [SerializeField] private bool _SetAlignment; [SerializeField] private SpriteAlignment _Alignment; [SerializeField] private bool _SetBorder; [SerializeField] private RectOffset _Border; [SerializeField] private bool _ShowDetails; /************************************************************************************************************************/ private enum OffsetRectMode { None, Add, Subtract } private static readonly string[] OffsetRectModes = { "None", "Add", "Subtract" }; private SerializedProperty _SerializedProperty; /************************************************************************************************************************/ /// public override int DisplayOrder => 1; /// public override string Name => "Modify Sprites"; /// public override string HelpURL => Strings.DocsURLs.ModifySprites; /// public override string Instructions { get { if (Sprites.Count == 0) return "Select the Sprites you want to modify."; if (!IsValidModification()) return "The current Rect Offset would move some Sprites outside the texture bounds."; return "Enter the desired modifications and click Apply."; } } /************************************************************************************************************************/ /// public override void OnEnable(int index) { base.OnEnable(index); _SerializedProperty = AnimancerToolsWindow.Instance.FindSerializedPropertyForTool(this); _SerializedProperty = _SerializedProperty.FindPropertyRelative(nameof(_RectMode)); } /************************************************************************************************************************/ /// public override void DoBodyGUI() { base.DoBodyGUI(); var area = AnimancerGUI.LayoutSingleLineRect(); area.xMin += 4; using (ObjectPool.Disposable.AcquireContent(out var label, "Offset Rects", null, false)) area = EditorGUI.PrefixLabel(area, label); AnimancerToolsWindow.BeginChangeCheck(); var selected = (OffsetRectMode)GUI.Toolbar(area, (int)_RectMode, OffsetRectModes); AnimancerToolsWindow.EndChangeCheck(ref _RectMode, selected); using (var property = _SerializedProperty.Copy()) { property.serializedObject.Update(); var depth = property.depth; while (property.Next(false) && property.depth >= depth) { EditorGUILayout.PropertyField(property, true); } property.serializedObject.ApplyModifiedProperties(); } GUI.enabled = false; for (int i = 0; i < Sprites.Count; i++) { if (_ShowDetails) GUILayout.BeginVertical(GUI.skin.box); var sprite = Sprites[i] = (Sprite)EditorGUILayout.ObjectField(Sprites[i], typeof(Sprite), false); if (_ShowDetails) { if (_RectMode != OffsetRectMode.None) EditorGUILayout.RectField("Rect", sprite.rect); if (_SetPivot) EditorGUILayout.Vector2Field("Pivot", sprite.pivot); if (_SetBorder) EditorGUILayout.Vector4Field("Border", sprite.border); GUILayout.EndVertical(); } } GUILayout.BeginHorizontal(); { GUILayout.FlexibleSpace(); GUI.enabled = Sprites.Count > 0 && IsValidModification(); if (GUILayout.Button("Apply")) { AnimancerGUI.Deselect(); AskAndApply(); } } GUILayout.EndHorizontal(); } /************************************************************************************************************************/ private bool IsValidModification() { switch (_RectMode) { default: case OffsetRectMode.None: return true; case OffsetRectMode.Add: case OffsetRectMode.Subtract: break; } var offset = GetOffset(); var sprites = Sprites; for (int i = 0; i < sprites.Count; i++) { var sprite = sprites[i]; var rect = Add(sprite.rect, offset); if (rect.xMin < 0 || rect.yMin < 0 || rect.xMax >= sprite.texture.width || rect.xMax >= sprite.texture.height) { return false; } } return true; } /************************************************************************************************************************/ private Rect GetOffset() { switch (_RectMode) { default: case OffsetRectMode.None: throw new InvalidOperationException($"Can't {nameof(GetOffset)} when the mode is {_RectMode}."); case OffsetRectMode.Add: return _RectOffset; case OffsetRectMode.Subtract: return new Rect(-_RectOffset.x, -_RectOffset.y, -_RectOffset.width, -_RectOffset.height); } } private static Rect Add(Rect a, Rect b) { a.x += b.x; a.y += b.y; a.width += b.width; a.height += b.height; return a; } /************************************************************************************************************************/ /// protected override string AreYouSure => "Are you sure you want to modify the borders of these Sprites?"; /************************************************************************************************************************/ /// protected override void Modify(SpriteDataEditor data, int index, Sprite sprite) { switch (_RectMode) { default: case OffsetRectMode.None: break; case OffsetRectMode.Add: case OffsetRectMode.Subtract: var rect = data.GetRect(index); rect = Add(rect, GetOffset()); data.SetRect(index, rect); break; } if (_SetPivot) data.SetPivot(index, _Pivot); if (_SetAlignment) data.SetAlignment(index, _Alignment); if (_SetBorder) data.SetBorder(index, new Vector4(_Border.left, _Border.bottom, _Border.right, _Border.top)); } /************************************************************************************************************************/ } } #endif