// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2023 Kybernetik // #if UNITY_EDITOR using System; using System.Collections.Generic; using UnityEditor; using UnityEditorInternal; using UnityEngine; namespace Animancer.Editor.Tools { /// [Editor-Only] [Pro-Only] /// An for changing which s an /// uses. /// /// /// Documentation: Remap Sprite Animation /// /// https://kybernetik.com.au/animancer/api/Animancer.Editor.Tools/RemapSpriteAnimationTool /// [Serializable] public class RemapSpriteAnimationTool : AnimationModifierTool { /************************************************************************************************************************/ [SerializeField] private List _NewSprites; [NonSerialized] private List _OldSprites; [NonSerialized] private bool _OldSpritesAreDirty; [NonSerialized] private ReorderableList _OldSpriteDisplay; [NonSerialized] private ReorderableList _NewSpriteDisplay; [NonSerialized] private EditorCurveBinding _SpriteBinding; [NonSerialized] private ObjectReferenceKeyframe[] _SpriteKeyframes; /************************************************************************************************************************/ /// public override int DisplayOrder => 4; /// public override string Name => "Remap Sprite Animation"; /// public override string HelpURL => Strings.DocsURLs.RemapSpriteAnimation; /// public override string Instructions { get { if (Animation == null) return "Select the animation you want to remap."; if (_OldSprites.Count == 0) return "The selected animation does not use Sprites."; return "Assign the New Sprites that you want to replace the Old Sprites with then click Save As." + " You can Drag and Drop multiple Sprites onto the New Sprites list at the same time."; } } /************************************************************************************************************************/ /// public override void OnEnable(int index) { base.OnEnable(index); if (_NewSprites == null) _NewSprites = new List(); if (Animation == null) _NewSprites.Clear(); _OldSprites = new List(); _OldSpriteDisplay = AnimancerToolsWindow.CreateReorderableObjectList(_OldSprites, "Old Sprites"); _NewSpriteDisplay = AnimancerToolsWindow.CreateReorderableObjectList(_NewSprites, "New Sprites"); } /************************************************************************************************************************/ /// protected override void OnAnimationChanged() { base.OnAnimationChanged(); _OldSpritesAreDirty = true; } /************************************************************************************************************************/ /// public override void DoBodyGUI() { base.DoBodyGUI(); GatherOldSprites(); GUILayout.BeginHorizontal(); { GUILayout.BeginVertical(); GUI.enabled = false; _OldSpriteDisplay.DoLayoutList(); GUI.enabled = true; GUILayout.EndVertical(); GUILayout.BeginVertical(); _NewSpriteDisplay.DoLayoutList(); GUILayout.EndVertical(); HandleDragAndDropIntoList(GUILayoutUtility.GetLastRect(), _NewSprites, overwrite: true); } GUILayout.EndHorizontal(); GUI.enabled = Animation != null; GUILayout.BeginHorizontal(); { GUILayout.FlexibleSpace(); if (GUILayout.Button("Reset")) { AnimancerGUI.Deselect(); AnimancerToolsWindow.RecordUndo(); _NewSprites.Clear(); _OldSpritesAreDirty = true; } if (GUILayout.Button("Save As")) { if (SaveAs()) { _OldSpritesAreDirty = true; } } } GUILayout.EndHorizontal(); } /************************************************************************************************************************/ /// Gathers the from the . private void GatherOldSprites() { if (!_OldSpritesAreDirty) return; _OldSpritesAreDirty = false; _OldSprites.Clear(); _NewSprites.Clear(); if (Animation == null) return; var bindings = AnimationUtility.GetObjectReferenceCurveBindings(Animation); for (int iBinding = 0; iBinding < bindings.Length; iBinding++) { var binding = bindings[iBinding]; if (binding.type == typeof(SpriteRenderer) && binding.propertyName == "m_Sprite") { _SpriteBinding = binding; _SpriteKeyframes = AnimationUtility.GetObjectReferenceCurve(Animation, binding); for (int iKeyframe = 0; iKeyframe < _SpriteKeyframes.Length; iKeyframe++) { var reference = _SpriteKeyframes[iKeyframe].value as Sprite; if (reference != null) _OldSprites.Add(reference); } _NewSprites.AddRange(_OldSprites); return; } } } /************************************************************************************************************************/ /// protected override void Modify(AnimationClip animation) { for (int i = 0; i < _SpriteKeyframes.Length; i++) { _SpriteKeyframes[i].value = _NewSprites[i]; } AnimationUtility.SetObjectReferenceCurve(animation, _SpriteBinding, _SpriteKeyframes); } /************************************************************************************************************************/ } } #endif