123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863 |
- // Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
- using System;
- using System.Collections.Generic;
- using System.Runtime.CompilerServices;
- using UnityEngine;
- using UnityEngine.Animations;
- using UnityEngine.Playables;
- using Object = UnityEngine.Object;
- namespace Animancer
- {
- /// <summary>[Pro-Only]
- /// An <see cref="AnimancerState"/> which plays a <see cref="RuntimeAnimatorController"/>.
- /// </summary>
- /// <remarks>
- /// This state can be controlled very similarly to an <see cref="Animator"/>
- /// via its <see cref="Playable"/> property.
- /// <para></para>
- /// <strong>Documentation:</strong>
- /// <see href="https://kybernetik.com.au/animancer/docs/manual/animator-controllers">
- /// Animator Controllers</see>
- /// </remarks>
- /// https://kybernetik.com.au/animancer/api/Animancer/ControllerState
- ///
- public partial class ControllerState : AnimancerState,
- ICopyable<ControllerState>,
- IParametizedState,
- IUpdatable
- {
- /************************************************************************************************************************/
- #region Fields and Properties
- /************************************************************************************************************************/
- private RuntimeAnimatorController _Controller;
- /// <summary>The <see cref="RuntimeAnimatorController"/> which this state plays.</summary>
- public RuntimeAnimatorController Controller
- {
- get => _Controller;
- set => ChangeMainObject(ref _Controller, value);
- }
- /// <summary>The <see cref="RuntimeAnimatorController"/> which this state plays.</summary>
- public override Object MainObject
- {
- get => Controller;
- set => Controller = (RuntimeAnimatorController)value;
- }
- #if UNITY_EDITOR
- /// <inheritdoc/>
- public override Type MainObjectType
- => typeof(RuntimeAnimatorController);
- #endif
- /************************************************************************************************************************/
- private new AnimatorControllerPlayable _Playable;
- /// <summary>The internal system which plays the <see cref="RuntimeAnimatorController"/>.</summary>
- public new AnimatorControllerPlayable Playable
- {
- get
- {
- Validate.AssertPlayable(this);
- return _Playable;
- }
- }
- /************************************************************************************************************************/
- /// <summary>Determines what a layer does when <see cref="AnimancerNode.Stop"/> is called.</summary>
- public enum ActionOnStop
- {
- /// <summary>Reset the layer to the first state it was in.</summary>
- DefaultState,
- /// <summary>Rewind the current state's time to 0.</summary>
- RewindTime,
- /// <summary>Allow the current state to stay at its current time.</summary>
- Continue,
- }
- /// <summary>Determines what each layer does when <see cref="AnimancerNode.Stop"/> is called.</summary>
- /// <remarks>
- /// If empty, all layers will reset to their <see cref="ActionOnStop.DefaultState"/>.
- /// <para></para>
- /// If this array is smaller than the <see cref="AnimatorControllerPlayable.GetLayerCount"/>,
- /// any additional layers will use the last value in this array.
- /// </remarks>
- public ActionOnStop[] ActionsOnStop { get; set; }
- /// <summary>
- /// The <see cref="AnimatorStateInfo.shortNameHash"/> of the default state on each layer,
- /// used to reset to those states when <see cref="ApplyActionsOnStop"/>
- /// is called for layers using <see cref="ActionOnStop.DefaultState"/>.
- /// </summary>
- /// <remarks>Gathered automatically by <see cref="GatherDefaultStates"/>.</remarks>
- public int[] DefaultStateHashes { get; set; }
- /************************************************************************************************************************/
- #if UNITY_ASSERTIONS
- /************************************************************************************************************************/
- /// <summary>[Assert-Only] Animancer Events work badly on <see cref="ControllerState"/>s.</summary>
- protected internal override string UnsupportedEventsMessage =>
- "Animancer Events on " + nameof(ControllerState) + "s will probably not work as expected." +
- " The events will be associated with the entire Animator Controller and be triggered by any of the" +
- " states inside it. If you want to use events in an Animator Controller you will likely need to use" +
- " Unity's regular Animation Event system.";
- /************************************************************************************************************************/
- #endif
- /************************************************************************************************************************/
- /// <summary>[Assert-Conditional] Asserts that the `value` is valid for a parameter.</summary>
- /// <exception cref="ArgumentOutOfRangeException">The `value` is NaN or Infinity.</exception>
- [System.Diagnostics.Conditional(Strings.Assertions)]
- public void AssertParameterValue(float value, [CallerMemberName] string parameterName = null)
- {
- if (!value.IsFinite())
- {
- MarkAsUsed(this);
- throw new ArgumentOutOfRangeException(parameterName, Strings.MustBeFinite);
- }
- }
- /************************************************************************************************************************/
- /// <summary>IK cannot be dynamically enabled on a <see cref="ControllerState"/>.</summary>
- public override void CopyIKFlags(AnimancerNodeBase copyFrom) { }
- /************************************************************************************************************************/
- /// <summary>IK cannot be dynamically enabled on a <see cref="ControllerState"/>.</summary>
- public override bool ApplyAnimatorIK
- {
- get => false;
- set
- {
- #if UNITY_ASSERTIONS
- if (value)
- OptionalWarning.UnsupportedIK.Log(
- $"IK cannot be dynamically enabled on a {nameof(ControllerState)}." +
- " You must instead enable it on the desired layer inside the Animator Controller.",
- _Controller);
- #endif
- }
- }
- /************************************************************************************************************************/
- /// <summary>IK cannot be dynamically enabled on a <see cref="ControllerState"/>.</summary>
- public override bool ApplyFootIK
- {
- get => false;
- set
- {
- #if UNITY_ASSERTIONS
- if (value)
- OptionalWarning.UnsupportedIK.Log(
- $"IK cannot be dynamically enabled on a {nameof(ControllerState)}." +
- " You must instead enable it on the desired state inside the Animator Controller.",
- _Controller);
- #endif
- }
- }
- /************************************************************************************************************************/
- /// <summary>Returns the hash of a parameter being wrapped by this state.</summary>
- /// <exception cref="NotSupportedException">This state doesn't wrap any parameters.</exception>
- public virtual int GetParameterHash(int index)
- {
- MarkAsUsed(this);
- throw new NotSupportedException();
- }
- /************************************************************************************************************************/
- /// <inheritdoc/>
- public virtual void GetParameters(List<StateParameterDetails> parameters) { }
- /// <inheritdoc/>
- public virtual void SetParameters(List<StateParameterDetails> parameters) { }
- /************************************************************************************************************************/
- #endregion
- /************************************************************************************************************************/
- #region Public API
- /************************************************************************************************************************/
- /// <summary>Creates a new <see cref="ControllerState"/> to play the `controller`.</summary>
- public ControllerState(RuntimeAnimatorController controller)
- {
- _Controller = controller != null
- ? controller
- : throw new ArgumentNullException(nameof(controller));
- }
- /// <summary>Creates a new <see cref="ControllerState"/> to play the `controller`.</summary>
- public ControllerState(RuntimeAnimatorController controller, params ActionOnStop[] actionsOnStop)
- : this(controller)
- {
- ActionsOnStop = actionsOnStop;
- }
- /************************************************************************************************************************/
- /// <summary>Creates and assigns the <see cref="AnimatorControllerPlayable"/> managed by this state.</summary>
- protected override void CreatePlayable(out Playable playable)
- {
- playable = _Playable = AnimatorControllerPlayable.Create(Graph._PlayableGraph, _Controller);
- GatherDefaultStates();
- DeserializeParameterBindings();
- }
- /************************************************************************************************************************/
- /// <summary>
- /// Stores the values of all parameters and calls <see cref="AnimancerNode.RecreatePlayable"/>,
- /// then restores the parameter values.
- /// </summary>
- public override void RecreatePlayable()
- {
- if (!_Playable.IsValid())
- {
- CreatePlayable();
- return;
- }
- var parameterCount = _Playable.GetParameterCount();
- var values = new object[parameterCount];
- for (int i = 0; i < parameterCount; i++)
- {
- values[i] = AnimancerUtilities.GetParameterValue(_Playable, _Playable.GetParameter(i));
- }
- base.RecreatePlayable();
- for (int i = 0; i < parameterCount; i++)
- {
- AnimancerUtilities.SetParameterValue(_Playable, _Playable.GetParameter(i), values[i]);
- }
- }
- /************************************************************************************************************************/
- /// <summary>
- /// Returns the current state on the specified `layer`,
- /// or the next state if it is currently in a transition.
- /// </summary>
- public AnimatorStateInfo GetStateInfo(int layerIndex)
- {
- if (!_Playable.IsValid())
- return default;
- Validate.AssertPlayable(this);
- return _Playable.IsInTransition(layerIndex)
- ? _Playable.GetNextAnimatorStateInfo(layerIndex)
- : _Playable.GetCurrentAnimatorStateInfo(layerIndex);
- }
- /************************************************************************************************************************/
- /// <summary>
- /// The <see cref="AnimatorStateInfo.normalizedTime"/> * <see cref="AnimatorStateInfo.length"/> of layer 0.
- /// </summary>
- public override double RawTime
- {
- get
- {
- var info = GetStateInfo(0);
- return info.normalizedTime * info.length;
- }
- set
- {
- Validate.AssertPlayable(this);
- _Playable.PlayInFixedTime(0, 0, (float)value);
- // Setting the time requires it to be playing.
- // This will leave it at the specified time.
- if (!IsPlaying)
- {
- _Playable.Play();
- Graph.RequirePostUpdate(this);
- }
- }
- }
- /************************************************************************************************************************/
- /// <inheritdoc/>
- int IUpdatable.UpdatableIndex { get; set; } = IUpdatable.List.NotInList;
- /************************************************************************************************************************/
- /// <summary>Pauses the <see cref="Playable"/> if necessary after <see cref="RawTime"/> was set.</summary>
- void IUpdatable.Update()
- {
- if (!IsPlaying)
- _Playable.Pause();
- AnimancerGraph.Current.CancelPostUpdate(this);
- }
- /************************************************************************************************************************/
- /// <inheritdoc/>
- public override void SetGraph(AnimancerGraph graph)
- {
- if (Graph == graph)
- return;
- Graph?.CancelPostUpdate(this);
- base.SetGraph(graph);
- }
- /************************************************************************************************************************/
- /// <summary>The current <see cref="AnimatorStateInfo.length"/> of layer 0.</summary>
- public override float Length => GetStateInfo(0).length;
- /************************************************************************************************************************/
- /// <summary>The current <see cref="AnimatorStateInfo.loop"/> of layer 0.</summary>
- public override bool IsLooping => GetStateInfo(0).loop;
- /************************************************************************************************************************/
- /// <inheritdoc/>
- public override void GetEventDispatchInfo(
- out float length,
- out float normalizedTime,
- out bool isLooping)
- {
- var state = GetStateInfo(0);
- length = state.length;
- normalizedTime = state.normalizedTime;
- isLooping = state.loop;
- }
- /************************************************************************************************************************/
- /// <summary>Gathers the <see cref="DefaultStateHashes"/> from the current states on each layer.</summary>
- /// <remarks>This is called by <see cref="CreatePlayable(out UnityEngine.Playables.Playable)"/>.</remarks>
- public void GatherDefaultStates()
- {
- Validate.AssertPlayable(this);
- var layerCount = _Playable.GetLayerCount();
- if (DefaultStateHashes == null || DefaultStateHashes.Length != layerCount)
- DefaultStateHashes = new int[layerCount];
- while (--layerCount >= 0)
- DefaultStateHashes[layerCount] = _Playable.GetCurrentAnimatorStateInfo(layerCount).shortNameHash;
- }
- /************************************************************************************************************************/
- /// <summary>
- /// Stops the animation and makes it inactive immediately so it no longer affects the output.
- /// Also calls <see cref="ApplyActionsOnStop"/>.
- /// </summary>
- protected internal override void StopWithoutWeight()
- {
- // Don't call base.StopWithoutWeight(); because it sets Time = 0;
- // which uses PlayInFixedTime and interferes with resetting to the default states.
- SetIsPlaying(false);
- UpdateIsActive();
- ApplyActionsOnStop();
- _SmoothingVelocities?.Clear();
- }
- /// <summary>Applies the <see cref="ActionsOnStop"/> to their corresponding layers.</summary>
- /// <exception cref="NullReferenceException"><see cref="DefaultStateHashes"/> is null.</exception>
- public void ApplyActionsOnStop()
- {
- Validate.AssertPlayable(this);
- var layerCount = Math.Min(DefaultStateHashes.Length, _Playable.GetLayerCount());
- if (ActionsOnStop == null || ActionsOnStop.Length == 0)
- {
- for (int i = layerCount - 1; i >= 0; i--)
- _Playable.Play(DefaultStateHashes[i], i, 0);
- }
- else
- {
- for (int i = layerCount - 1; i >= 0; i--)
- {
- var index = i < ActionsOnStop.Length
- ? i
- : ActionsOnStop.Length - 1;
- switch (ActionsOnStop[index])
- {
- case ActionOnStop.DefaultState:
- _Playable.Play(DefaultStateHashes[i], i, 0);
- break;
- case ActionOnStop.RewindTime:
- _Playable.Play(0, i, 0);
- break;
- case ActionOnStop.Continue:
- break;
- }
- }
- }
- }
- /************************************************************************************************************************/
- /// <inheritdoc/>
- public override void GatherAnimationClips(ICollection<AnimationClip> clips)
- {
- if (_Controller != null)
- clips.Gather(_Controller.animationClips);
- }
- /************************************************************************************************************************/
- /// <inheritdoc/>
- public override void Destroy()
- {
- _Controller = null;
- DisposeParameterBindings();
- base.Destroy();
- }
- /************************************************************************************************************************/
- /// <inheritdoc/>
- public override AnimancerState Clone(CloneContext context)
- {
- var clone = new ControllerState(_Controller);
- clone.CopyFrom(this, context);
- return clone;
- }
- /************************************************************************************************************************/
- /// <inheritdoc/>
- public sealed override void CopyFrom(AnimancerState copyFrom, CloneContext context)
- => this.CopyFromBase(copyFrom, context);
- /// <inheritdoc/>
- public virtual void CopyFrom(ControllerState copyFrom, CloneContext context)
- {
- ActionsOnStop = copyFrom.ActionsOnStop;
- if (copyFrom.Graph != null &&
- Graph != null)
- {
- var layerCount = copyFrom._Playable.GetLayerCount();
- for (int i = 0; i < layerCount; i++)
- {
- var info = copyFrom._Playable.GetCurrentAnimatorStateInfo(i);
- _Playable.Play(info.shortNameHash, i, info.normalizedTime);
- }
- var parameterCount = copyFrom._Playable.GetParameterCount();
- for (int i = 0; i < parameterCount; i++)
- {
- AnimancerUtilities.CopyParameterValue(
- copyFrom._Playable,
- _Playable,
- copyFrom._Playable.GetParameter(i));
- }
- }
- CopySmoothingVelocitiesFrom(copyFrom);
- base.CopyFrom(copyFrom, context);
- }
- /************************************************************************************************************************/
- #endregion
- /************************************************************************************************************************/
- #region Animator Controller Wrappers
- /************************************************************************************************************************/
- #region Cross Fade
- /************************************************************************************************************************/
- /// <summary>
- /// The default constant for fade duration parameters which causes it to use the
- /// <see cref="AnimancerGraph.DefaultFadeDuration"/> instead.
- /// </summary>
- public const float DefaultFadeDuration = -1;
- /************************************************************************************************************************/
- /// <summary>
- /// Returns the `fadeDuration` if it is zero or positive.
- /// Otherwise returns the <see cref="AnimancerGraph.DefaultFadeDuration"/>.
- /// </summary>
- public static float GetFadeDuration(float fadeDuration)
- => fadeDuration >= 0
- ? fadeDuration
- : AnimancerGraph.DefaultFadeDuration;
- /************************************************************************************************************************/
- /// <summary>Starts a transition from the current state to the specified state using normalized times.</summary>
- /// <remarks>If `fadeDuration` is negative, it uses the <see cref="AnimancerGraph.DefaultFadeDuration"/>.</remarks>
- public void CrossFade(
- int stateNameHash,
- float fadeDuration = DefaultFadeDuration,
- int layer = -1,
- float normalizedTime = float.NegativeInfinity)
- => Playable.CrossFade(stateNameHash, GetFadeDuration(fadeDuration), layer, normalizedTime);
- /************************************************************************************************************************/
- /// <summary>Starts a transition from the current state to the specified state using normalized times.</summary>
- /// <remarks>If `fadeDuration` is negative, it uses the <see cref="AnimancerGraph.DefaultFadeDuration"/>.</remarks>
- public void CrossFade(
- string stateName,
- float fadeDuration = DefaultFadeDuration,
- int layer = -1,
- float normalizedTime = float.NegativeInfinity)
- => Playable.CrossFade(stateName, GetFadeDuration(fadeDuration), layer, normalizedTime);
- /************************************************************************************************************************/
- /// <summary>Starts a transition from the current state to the specified state using times in seconds.</summary>
- /// <remarks>If `fadeDuration` is negative, it uses the <see cref="AnimancerGraph.DefaultFadeDuration"/>.</remarks>
- public void CrossFadeInFixedTime(
- int stateNameHash,
- float fadeDuration = DefaultFadeDuration,
- int layer = -1,
- float fixedTime = 0)
- => Playable.CrossFadeInFixedTime(stateNameHash, GetFadeDuration(fadeDuration), layer, fixedTime);
- /************************************************************************************************************************/
- /// <summary>Starts a transition from the current state to the specified state using times in seconds.</summary>
- /// <remarks>If `fadeDuration` is negative, it uses the <see cref="AnimancerGraph.DefaultFadeDuration"/>.</remarks>
- public void CrossFadeInFixedTime(
- string stateName,
- float fadeDuration = DefaultFadeDuration,
- int layer = -1,
- float fixedTime = 0)
- => Playable.CrossFadeInFixedTime(stateName, GetFadeDuration(fadeDuration), layer, fixedTime);
- /************************************************************************************************************************/
- #endregion
- /************************************************************************************************************************/
- #region Play
- /************************************************************************************************************************/
- /// <summary>Plays the specified state immediately, starting from a particular normalized time.</summary>
- public void Play(
- int stateNameHash,
- int layer = -1,
- float normalizedTime = float.NegativeInfinity)
- => Playable.Play(stateNameHash, layer, normalizedTime);
- /************************************************************************************************************************/
- /// <summary>Plays the specified state immediately, starting from a particular normalized time.</summary>
- public void Play(
- string stateName,
- int layer = -1,
- float normalizedTime = float.NegativeInfinity)
- => Playable.Play(stateName, layer, normalizedTime);
- /************************************************************************************************************************/
- /// <summary>Plays the specified state immediately, starting from a particular time (in seconds).</summary>
- public void PlayInFixedTime(
- int stateNameHash,
- int layer = -1,
- float fixedTime = 0)
- => Playable.PlayInFixedTime(stateNameHash, layer, fixedTime);
- /************************************************************************************************************************/
- /// <summary>Plays the specified state immediately, starting from a particular time (in seconds).</summary>
- public void PlayInFixedTime(
- string stateName,
- int layer = -1,
- float fixedTime = 0)
- => Playable.PlayInFixedTime(stateName, layer, fixedTime);
- /************************************************************************************************************************/
- #endregion
- /************************************************************************************************************************/
- #region Parameters
- /************************************************************************************************************************/
- /// <summary>Gets the value of the specified boolean parameter.</summary>
- public bool GetBool(int id)
- => Playable.GetBool(id);
- /// <summary>Gets the value of the specified boolean parameter.</summary>
- public bool GetBool(string name)
- => Playable.GetBool(name);
- /// <summary>Sets the value of the specified boolean parameter.</summary>
- public void SetBool(int id, bool value)
- => Playable.SetBool(id, value);
- /// <summary>Sets the value of the specified boolean parameter.</summary>
- public void SetBool(string name, bool value)
- => Playable.SetBool(name, value);
- /// <summary>Gets the value of the specified float parameter.</summary>
- public float GetFloat(int id)
- => Playable.GetFloat(id);
- /// <summary>Gets the value of the specified float parameter.</summary>
- public float GetFloat(string name)
- => Playable.GetFloat(name);
- /// <summary>Sets the value of the specified float parameter.</summary>
- public void SetFloat(int id, float value)
- => Playable.SetFloat(id, value);
- /// <summary>Sets the value of the specified float parameter.</summary>
- public void SetFloat(string name, float value)
- => Playable.SetFloat(name, value);
- /// <summary>Gets the value of the specified integer parameter.</summary>
- public int GetInteger(int id)
- => Playable.GetInteger(id);
- /// <summary>Gets the value of the specified integer parameter.</summary>
- public int GetInteger(string name)
- => Playable.GetInteger(name);
- /// <summary>Sets the value of the specified integer parameter.</summary>
- public void SetInteger(int id, int value)
- => Playable.SetInteger(id, value);
- /// <summary>Sets the value of the specified integer parameter.</summary>
- public void SetInteger(string name, int value)
- => Playable.SetInteger(name, value);
- /// <summary>Sets the specified trigger parameter to true.</summary>
- public void SetTrigger(int id)
- => Playable.SetTrigger(id);
- /// <summary>Sets the specified trigger parameter to true.</summary>
- ///
- public void SetTrigger(string name)
- => Playable.SetTrigger(name);
- /// <summary>Resets the specified trigger parameter to false.</summary>
- ///
- public void ResetTrigger(int id)
- => Playable.ResetTrigger(id);
- /// <summary>Resets the specified trigger parameter to false.</summary>
- ///
- public void ResetTrigger(string name)
- => Playable.ResetTrigger(name);
- /// <summary>Indicates whether the specified parameter is controlled by an <see cref="AnimationClip"/>.</summary>
- public bool IsParameterControlledByCurve(int id)
- => Playable.IsParameterControlledByCurve(id);
- /// <summary>Indicates whether the specified parameter is controlled by an <see cref="AnimationClip"/>.</summary>
- public bool IsParameterControlledByCurve(string name)
- => Playable.IsParameterControlledByCurve(name);
- /// <summary>Gets the details of one of the <see cref="Controller"/>'s parameters.</summary>
- public AnimatorControllerParameter GetParameter(int index)
- => Playable.GetParameter(index);
- /// <summary>Gets the number of parameters in the <see cref="Controller"/>.</summary>
- public int GetParameterCount()
- => Playable.GetParameterCount();
- /************************************************************************************************************************/
- /// <summary>The number of parameters in the <see cref="Controller"/>.</summary>
- public int parameterCount => Playable.GetParameterCount();
- /************************************************************************************************************************/
- private AnimatorControllerParameter[] _Parameters;
- /// <summary>The parameters in the <see cref="Controller"/>.</summary>
- /// <remarks>
- /// This property allocates a new array when first accessed. To avoid that, you can use
- /// <see cref="GetParameterCount"/> and <see cref="GetParameter"/> instead.
- /// </remarks>
- public AnimatorControllerParameter[] parameters
- {
- get
- {
- if (_Parameters == null)
- {
- var count = GetParameterCount();
- _Parameters = new AnimatorControllerParameter[count];
- for (int i = 0; i < count; i++)
- _Parameters[i] = GetParameter(i);
- }
- return _Parameters;
- }
- }
- /************************************************************************************************************************/
- #endregion
- /************************************************************************************************************************/
- #region Smoothed Set Float
- /************************************************************************************************************************/
- private Dictionary<int, float> _SmoothingVelocities;
- /************************************************************************************************************************/
- /// <summary>Sets the value of the specified float parameter with smoothing.</summary>
- /// <remarks>Consider using a <see cref="SmoothedFloatParameter"/> instead.</remarks>
- public float SetFloat(
- string name,
- float value,
- float dampTime,
- float deltaTime,
- float maxSpeed = float.PositiveInfinity)
- => SetFloat(Animator.StringToHash(name), value, dampTime, deltaTime, maxSpeed);
- /// <summary>Sets the value of the specified float parameter with smoothing.</summary>
- /// <remarks>Consider using a <see cref="SmoothedFloatParameter"/> instead.</remarks>
- public float SetFloat(
- int id,
- float value,
- float dampTime,
- float deltaTime,
- float maxSpeed = float.PositiveInfinity)
- {
- _SmoothingVelocities ??= new();
- _SmoothingVelocities.TryGetValue(id, out var velocity);
- value = Mathf.SmoothDamp(GetFloat(id), value, ref velocity, dampTime, maxSpeed, deltaTime);
- SetFloat(id, value);
- _SmoothingVelocities[id] = velocity;
- return value;
- }
- /************************************************************************************************************************/
- /// <summary>Copies the smoothing velocities.</summary>
- private void CopySmoothingVelocitiesFrom(ControllerState copyFrom)
- {
- if (copyFrom._SmoothingVelocities != null)
- {
- if (_SmoothingVelocities == null)
- _SmoothingVelocities = new();
- else
- _SmoothingVelocities.Clear();
- foreach (var item in copyFrom._SmoothingVelocities)
- _SmoothingVelocities[item.Key] = item.Value;
- }
- else
- {
- _SmoothingVelocities?.Clear();
- }
- }
- /************************************************************************************************************************/
- #endregion
- /************************************************************************************************************************/
- #region Misc
- /************************************************************************************************************************/
- // Layers.
- /************************************************************************************************************************/
- /// <summary>Gets the weight of the layer at the specified index.</summary>
- public float GetLayerWeight(int layerIndex)
- => Playable.GetLayerWeight(layerIndex);
- /// <summary>Sets the weight of the layer at the specified index.</summary>
- public void SetLayerWeight(int layerIndex, float weight)
- => Playable.SetLayerWeight(layerIndex, weight);
- /// <summary>Gets the number of layers in the <see cref="Controller"/>.</summary>
- public int GetLayerCount()
- => Playable.GetLayerCount();
- /// <summary>The number of layers in the <see cref="Controller"/>.</summary>
- public int layerCount
- => Playable.GetLayerCount();
- /// <summary>Gets the index of the layer with the specified name.</summary>
- public int GetLayerIndex(string layerName)
- => Playable.GetLayerIndex(layerName);
- /// <summary>Gets the name of the layer with the specified index.</summary>
- public string GetLayerName(int layerIndex)
- => Playable.GetLayerName(layerIndex);
- /************************************************************************************************************************/
- // States.
- /************************************************************************************************************************/
- /// <summary>Returns information about the current state.</summary>
- public AnimatorStateInfo GetCurrentAnimatorStateInfo(int layerIndex = 0)
- => Playable.GetCurrentAnimatorStateInfo(layerIndex);
- /// <summary>Returns information about the next state being transitioned towards.</summary>
- public AnimatorStateInfo GetNextAnimatorStateInfo(int layerIndex = 0)
- => Playable.GetNextAnimatorStateInfo(layerIndex);
- /// <summary>Indicates whether the specified layer contains the specified state.</summary>
- public bool HasState(int layerIndex, int stateID)
- => Playable.HasState(layerIndex, stateID);
- /************************************************************************************************************************/
- // Transitions.
- /************************************************************************************************************************/
- /// <summary>Indicates whether the specified layer is currently executing a transition.</summary>
- public bool IsInTransition(int layerIndex = 0)
- => Playable.IsInTransition(layerIndex);
- /// <summary>Gets information about the current transition.</summary>
- public AnimatorTransitionInfo GetAnimatorTransitionInfo(int layerIndex = 0)
- => Playable.GetAnimatorTransitionInfo(layerIndex);
- /************************************************************************************************************************/
- // Clips.
- /************************************************************************************************************************/
- /// <summary>Gets information about the <see cref="AnimationClip"/>s currently being played.</summary>
- public AnimatorClipInfo[] GetCurrentAnimatorClipInfo(int layerIndex = 0)
- => Playable.GetCurrentAnimatorClipInfo(layerIndex);
- /// <summary>Gets information about the <see cref="AnimationClip"/>s currently being played.</summary>
- public void GetCurrentAnimatorClipInfo(int layerIndex, List<AnimatorClipInfo> clips)
- => Playable.GetCurrentAnimatorClipInfo(layerIndex, clips);
- /// <summary>Gets the number of <see cref="AnimationClip"/>s currently being played.</summary>
- ///
- public int GetCurrentAnimatorClipInfoCount(int layerIndex = 0)
- => Playable.GetCurrentAnimatorClipInfoCount(layerIndex);
- /// <summary>Gets information about the <see cref="AnimationClip"/>s currently being transitioned towards.</summary>
- public AnimatorClipInfo[] GetNextAnimatorClipInfo(int layerIndex = 0)
- => Playable.GetNextAnimatorClipInfo(layerIndex);
- /// <summary>Gets information about the <see cref="AnimationClip"/>s currently being transitioned towards.</summary>
- public void GetNextAnimatorClipInfo(int layerIndex, List<AnimatorClipInfo> clips)
- => Playable.GetNextAnimatorClipInfo(layerIndex, clips);
- /// <summary>Gets the number of <see cref="AnimationClip"/>s currently being transitioned towards.</summary>
- public int GetNextAnimatorClipInfoCount(int layerIndex = 0)
- => Playable.GetNextAnimatorClipInfoCount(layerIndex);
- /************************************************************************************************************************/
- #endregion
- /************************************************************************************************************************/
- #endregion
- /************************************************************************************************************************/
- }
- }
|