// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2023 Kybernetik // using System; using System.Collections.Generic; using UnityEngine; #if UNITY_EDITOR using Animancer.Editor; using UnityEditor; #endif namespace Animancer { /// A which gets its clip from a . /// /// Documentation: Directional Animation Sets /// /// /// // Leave the Clip field empty in the Inspector and assign its AnimationSet instead. /// [SerializeField] private DirectionalClipTransition _Transition; /// /// ... /// /// // Then you can just call SetDirection and Play it like any other transition. /// // All of the transition's details like Fade Duration and Events will be applied to whichever clip is plays. /// _Transition.SetDirection(Vector2.right); /// _Animancer.Play(_Transition); /// /// https://kybernetik.com.au/animancer/api/Animancer/DirectionalClipTransition /// [Serializable] public class DirectionalClipTransition : ClipTransition, ICopyable { /************************************************************************************************************************/ [SerializeField] [Tooltip("The animations which used to determine the " + nameof(Clip))] private DirectionalAnimationSet _AnimationSet; /// [] /// The used to determine the . /// public ref DirectionalAnimationSet AnimationSet => ref _AnimationSet; /// public override UnityEngine.Object MainObject => _AnimationSet; /************************************************************************************************************************/ /// Sets the from the . public void SetDirection(Vector2 direction) => Clip = _AnimationSet.GetClip(direction); /// Sets the from the . public void SetDirection(int direction) => Clip = _AnimationSet.GetClip(direction); /// Sets the from the . public void SetDirection(DirectionalAnimationSet.Direction direction) => Clip = _AnimationSet.GetClip(direction); /// Sets the from the . public void SetDirection(DirectionalAnimationSet8.Direction direction) => Clip = _AnimationSet.GetClip((int)direction); /************************************************************************************************************************/ /// public override void GatherAnimationClips(ICollection clips) { base.GatherAnimationClips(clips); clips.GatherFromSource(_AnimationSet); } /************************************************************************************************************************/ /// public virtual void CopyFrom(DirectionalClipTransition copyFrom) { base.CopyFrom(copyFrom); if (copyFrom == null) { _AnimationSet = default; return; } _AnimationSet = copyFrom._AnimationSet; } /************************************************************************************************************************/ #if UNITY_EDITOR /************************************************************************************************************************/ /// [CustomPropertyDrawer(typeof(DirectionalClipTransition), true)] public new class Drawer : TransitionDrawer { /************************************************************************************************************************/ /// Creates a new . public Drawer() : base(nameof(_AnimationSet)) { } /************************************************************************************************************************/ /// protected override void DoChildPropertyGUI( ref Rect area, SerializedProperty rootProperty, SerializedProperty property, GUIContent label) { var width = area.width; var path = property.propertyPath; if (path.EndsWith($".{ClipFieldName}")) { if (property.objectReferenceValue != null) { var removeArea = AnimancerGUI.StealFromRight( ref area, AnimancerGUI.LineHeight, AnimancerGUI.StandardSpacing); using (ObjectPool.Disposable.AcquireContent(out var removeLabel, "X", $"A {nameof(DirectionalClipTransition)} will get its Clip from the Animation Set" + $" at runtime so the Clip might as well be null until then.")) { if (GUI.Button(removeArea, removeLabel, AnimancerGUI.MiniButton)) property.objectReferenceValue = null; } } if (Context.Transition is DirectionalClipTransition directionalClipTransition && directionalClipTransition._AnimationSet != null) { var dropdownArea = AnimancerGUI.StealFromRight( ref area, area.height, AnimancerGUI.StandardSpacing); if (GUI.Button(dropdownArea, GUIContent.none, EditorStyles.popup)) PickAnimation(property, directionalClipTransition); } } base.DoChildPropertyGUI(ref area, rootProperty, property, label); area.width = width; } /************************************************************************************************************************/ /// Shows a context menu to choose an from the `source`. private void PickAnimation(SerializedProperty property, object source) { var menu = new GenericMenu(); using (ObjectPool.Disposable.AcquireSet(out var clips)) { clips.GatherFromSource(source); if (clips.Count == 0) return; property = property.Copy(); foreach (var clip in clips) { menu.AddPropertyModifierFunction(property, clip.name, true, modify => { modify.objectReferenceValue = clip; }); } } menu.ShowAsContext(); } /************************************************************************************************************************/ } /************************************************************************************************************************/ #endif /************************************************************************************************************************/ } }