// Animancer // Copyright 2020 Kybernetik // using System.Collections.Generic; using UnityEngine; namespace Animancer { /// <summary> /// A <see cref="ScriptableObject"/> based <see cref="ITransition"/>s which can create a /// <see cref="ClipState"/> when passed into <see cref="AnimancerPlayable.Play(ITransition)"/>. /// </summary> /// <remarks> /// When adding a <see cref="CreateAssetMenuAttribute"/> to any derived classes, you can use /// <see cref="Strings.MenuPrefix"/> and <see cref="Strings.AssetMenuOrder"/>. /// </remarks> public abstract class AnimancerTransition : ScriptableObject, ITransition, IAnimationClipSource { /************************************************************************************************************************/ /// <summary> /// Returns the <see cref="ITransition"/> wrapped by this <see cref="ScriptableObject"/>. /// </summary> public abstract ITransition GetTransition(); /************************************************************************************************************************/ /// <summary>Wraps <see cref="ITransition.FadeDuration"/>.</summary> public float FadeDuration { get { return GetTransition().FadeDuration; } } /// <summary>Wraps <see cref="IHasKey.Key"/>.</summary> public object Key { get { return GetTransition().Key; } } /// <summary>Wraps <see cref="ITransition.FadeMode"/>.</summary> public FadeMode FadeMode { get { return GetTransition().FadeMode; } } /// <summary>Wraps <see cref="ITransition.CreateState"/>.</summary> public AnimancerState CreateState(AnimancerLayer layer) { return GetTransition().CreateState(layer); } /// <summary>Wraps <see cref="ITransition.Apply"/>.</summary> public void Apply(AnimancerState state) { GetTransition().Apply(state); } /************************************************************************************************************************/ /// <summary>Wraps <see cref="AnimancerUtilities.GatherFromSource(ICollection{AnimationClip}, object)"/>.</summary> public void GetAnimationClips(List<AnimationClip> clips) { clips.GatherFromSource(GetTransition()); } /************************************************************************************************************************/ } /************************************************************************************************************************/ /// <summary> /// An <see cref="AnimancerTransition"/> which uses a generic field for its <see cref="ITransition"/>. /// </summary> public class AnimancerTransition<T> : AnimancerTransition where T : ITransition { /************************************************************************************************************************/ [SerializeField] [UnityEngine.Serialization.FormerlySerializedAs("_Animation")] private T _Transition; /// <summary>[<see cref="SerializeField"/>] /// The <see cref="ITransition"/> wrapped by this <see cref="ScriptableObject"/>. /// <para></para> /// WARNING: the <see cref="AnimancerState.Transition{TState}.State"/> holds the post recently played state, so /// if you are sharing this transition between multiple objects it will only remember one of them. /// <para></para> /// You can use <see cref="AnimancerPlayable.StateDictionary.GetOrCreate(ITransition)"/> or /// <see cref="AnimancerLayer.GetOrCreateState(ITransition)"/> to get or create the state for a /// specific object. /// </summary> public T Transition { get { return _Transition; } set { _Transition = value; } } /// <summary> /// Returns the <see cref="ITransition"/> wrapped by this <see cref="ScriptableObject"/>. /// </summary> public override ITransition GetTransition() { return _Transition; } /************************************************************************************************************************/ } /************************************************************************************************************************/ #if UNITY_EDITOR namespace Editor { [UnityEditor.CustomEditor(typeof(AnimancerTransition), true)] internal class AnimancerTransitionEditor : ScriptableObjectEditor { } } #endif }