123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599 |
- using System;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.Animations;
- using UnityEngine.Playables;
- using Object = UnityEngine.Object;
- using System.Runtime.CompilerServices;
- namespace Animancer
- {
-
-
-
-
-
-
-
-
- public partial class ControllerState : AnimancerState
- {
-
-
- public interface ITransition : ITransition<ControllerState> { }
-
- #region Fields and Properties
-
- private RuntimeAnimatorController _Controller;
-
- public RuntimeAnimatorController Controller
- {
- get => _Controller;
- set => ChangeMainObject(ref _Controller, value);
- }
-
- public override Object MainObject
- {
- get => Controller;
- set => Controller = (RuntimeAnimatorController)value;
- }
-
- public AnimatorControllerPlayable Playable
- {
- get
- {
- Validate.AssertPlayable(this);
- return _Playable;
- }
- }
- private new AnimatorControllerPlayable _Playable;
-
-
- public enum ActionOnStop
- {
-
- DefaultState,
-
- RewindTime,
-
- Continue,
- }
- private ActionOnStop[] _ActionsOnStop;
-
-
-
-
-
-
-
- public ActionOnStop[] ActionsOnStop
- {
- get => _ActionsOnStop;
- set
- {
- _ActionsOnStop = value;
- if (_Playable.IsValid())
- GatherDefaultStates();
- }
- }
-
-
-
-
-
-
- public int[] DefaultStateHashes { get; set; }
-
- #if UNITY_ASSERTIONS
-
- protected 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.";
-
-
-
- protected override string UnsupportedSpeedMessage =>
- nameof(PlayableExtensions) + "." + nameof(PlayableExtensions.SetSpeed) + " does nothing on " + nameof(ControllerState) +
- "s so there is no way to directly control their speed." +
- " The Animator Controller Speed page explains a possible workaround for this issue:" +
- " https://kybernetik.com.au/animancer/docs/bugs/animator-controller-speed";
- #endif
-
-
-
- [System.Diagnostics.Conditional(Strings.Assertions)]
- public void AssertParameterValue(float value, [CallerMemberName] string parameterName = null)
- {
- if (!value.IsFinite())
- throw new ArgumentOutOfRangeException(parameterName, Strings.MustBeFinite);
- }
-
-
- public override void CopyIKFlags(AnimancerNode node) { }
-
-
- 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
- }
- }
-
-
- 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
- }
- }
-
-
- public virtual int ParameterCount => 0;
-
-
- public virtual int GetParameterHash(int index) => throw new NotSupportedException();
-
- #endregion
-
- #region Public API
-
-
- public ControllerState(RuntimeAnimatorController controller)
- {
- if (controller == null)
- throw new ArgumentNullException(nameof(controller));
- _Controller = controller;
- }
-
- public ControllerState(RuntimeAnimatorController controller, params ActionOnStop[] actionsOnStop)
- : this(controller)
- {
- _ActionsOnStop = actionsOnStop;
- }
-
-
- protected override void CreatePlayable(out Playable playable)
- {
- playable = _Playable = AnimatorControllerPlayable.Create(Root._Graph, _Controller);
- GatherDefaultStates();
- }
-
-
-
-
-
- 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]);
- }
- }
-
-
-
-
- public AnimatorStateInfo GetStateInfo(int layerIndex)
- {
- Validate.AssertPlayable(this);
- return _Playable.IsInTransition(layerIndex) ?
- _Playable.GetNextAnimatorStateInfo(layerIndex) :
- _Playable.GetCurrentAnimatorStateInfo(layerIndex);
- }
-
-
-
-
- protected override float RawTime
- {
- get
- {
- var info = GetStateInfo(0);
- return info.normalizedTime * info.length;
- }
- set
- {
- Validate.AssertPlayable(this);
- _Playable.PlayInFixedTime(0, 0, value);
- if (!IsPlaying)
- {
- _Playable.Play();
- DelayedPause.Register(this);
- }
- }
- }
-
-
- public override float Length => GetStateInfo(0).length;
-
-
- public override bool IsLooping => GetStateInfo(0).loop;
-
-
- 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;
- }
-
-
-
-
-
- public override void Stop()
- {
-
-
- Weight = 0;
- IsPlaying = false;
- if (AutomaticallyClearEvents)
- Events = null;
- ApplyActionsOnStop();
- }
-
-
- 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;
- }
- }
- }
-
-
- CancelSetTime();
- }
-
-
- public override void GatherAnimationClips(ICollection<AnimationClip> clips)
- {
- if (_Controller != null)
- clips.Gather(_Controller.animationClips);
- }
-
-
- public override void Destroy()
- {
- _Controller = null;
- base.Destroy();
- }
-
- #endregion
-
- #region Animator Controller Wrappers
-
- #region Cross Fade
-
-
-
-
-
- public const float DefaultFadeDuration = -1;
-
-
-
-
-
- public static float GetFadeDuration(float fadeDuration)
- => fadeDuration >= 0 ? fadeDuration : AnimancerPlayable.DefaultFadeDuration;
-
-
-
- public void CrossFade(int stateNameHash,
- float fadeDuration = DefaultFadeDuration,
- int layer = -1,
- float normalizedTime = float.NegativeInfinity)
- => Playable.CrossFade(stateNameHash, GetFadeDuration(fadeDuration), layer, normalizedTime);
-
-
-
- public void CrossFade(string stateName,
- float fadeDuration = DefaultFadeDuration,
- int layer = -1,
- float normalizedTime = float.NegativeInfinity)
- => Playable.CrossFade(stateName, GetFadeDuration(fadeDuration), layer, normalizedTime);
-
-
-
- public void CrossFadeInFixedTime(int stateNameHash,
- float fadeDuration = DefaultFadeDuration,
- int layer = -1,
- float fixedTime = 0)
- => Playable.CrossFadeInFixedTime(stateNameHash, GetFadeDuration(fadeDuration), layer, fixedTime);
-
-
-
- public void CrossFadeInFixedTime(string stateName,
- float fadeDuration = DefaultFadeDuration,
- int layer = -1,
- float fixedTime = 0)
- => Playable.CrossFadeInFixedTime(stateName, GetFadeDuration(fadeDuration), layer, fixedTime);
-
- #endregion
-
- #region Play
-
-
- public void Play(int stateNameHash,
- int layer = -1,
- float normalizedTime = float.NegativeInfinity)
- => Playable.Play(stateNameHash, layer, normalizedTime);
-
-
- public void Play(string stateName,
- int layer = -1,
- float normalizedTime = float.NegativeInfinity)
- => Playable.Play(stateName, layer, normalizedTime);
-
-
- public void PlayInFixedTime(int stateNameHash,
- int layer = -1,
- float fixedTime = 0)
- => Playable.PlayInFixedTime(stateNameHash, layer, fixedTime);
-
-
- public void PlayInFixedTime(string stateName,
- int layer = -1,
- float fixedTime = 0)
- => Playable.PlayInFixedTime(stateName, layer, fixedTime);
-
- #endregion
-
- #region Parameters
-
-
- public bool GetBool(int id) => Playable.GetBool(id);
-
- public bool GetBool(string name) => Playable.GetBool(name);
-
- public void SetBool(int id, bool value) => Playable.SetBool(id, value);
-
- public void SetBool(string name, bool value) => Playable.SetBool(name, value);
-
- public float GetFloat(int id) => Playable.GetFloat(id);
-
- public float GetFloat(string name) => Playable.GetFloat(name);
-
- public void SetFloat(int id, float value) => Playable.SetFloat(id, value);
-
- public void SetFloat(string name, float value) => Playable.SetFloat(name, value);
-
- public int GetInteger(int id) => Playable.GetInteger(id);
-
- public int GetInteger(string name) => Playable.GetInteger(name);
-
- public void SetInteger(int id, int value) => Playable.SetInteger(id, value);
-
- public void SetInteger(string name, int value) => Playable.SetInteger(name, value);
-
- public void SetTrigger(int id) => Playable.SetTrigger(id);
-
- public void SetTrigger(string name) => Playable.SetTrigger(name);
-
- public void ResetTrigger(int id) => Playable.ResetTrigger(id);
-
- public void ResetTrigger(string name) => Playable.ResetTrigger(name);
-
- public AnimatorControllerParameter GetParameter(int index) => Playable.GetParameter(index);
-
- public int GetParameterCount() => Playable.GetParameterCount();
-
- public bool IsParameterControlledByCurve(int id) => Playable.IsParameterControlledByCurve(id);
-
- public bool IsParameterControlledByCurve(string name) => Playable.IsParameterControlledByCurve(name);
-
- #endregion
-
- #region Misc
-
-
-
-
- public float GetLayerWeight(int layerIndex) => Playable.GetLayerWeight(layerIndex);
-
- public void SetLayerWeight(int layerIndex, float weight) => Playable.SetLayerWeight(layerIndex, weight);
-
- public int GetLayerCount() => Playable.GetLayerCount();
-
- public int GetLayerIndex(string layerName) => Playable.GetLayerIndex(layerName);
-
- public string GetLayerName(int layerIndex) => Playable.GetLayerName(layerIndex);
-
-
-
-
- public AnimatorStateInfo GetCurrentAnimatorStateInfo(int layerIndex = 0) => Playable.GetCurrentAnimatorStateInfo(layerIndex);
-
- public AnimatorStateInfo GetNextAnimatorStateInfo(int layerIndex = 0) => Playable.GetNextAnimatorStateInfo(layerIndex);
-
- public bool HasState(int layerIndex, int stateID) => Playable.HasState(layerIndex, stateID);
-
-
-
-
- public bool IsInTransition(int layerIndex = 0) => Playable.IsInTransition(layerIndex);
-
- public AnimatorTransitionInfo GetAnimatorTransitionInfo(int layerIndex = 0) => Playable.GetAnimatorTransitionInfo(layerIndex);
-
-
-
-
- public AnimatorClipInfo[] GetCurrentAnimatorClipInfo(int layerIndex = 0) => Playable.GetCurrentAnimatorClipInfo(layerIndex);
-
- public void GetCurrentAnimatorClipInfo(int layerIndex, List<AnimatorClipInfo> clips) => Playable.GetCurrentAnimatorClipInfo(layerIndex, clips);
-
- public int GetCurrentAnimatorClipInfoCount(int layerIndex = 0) => Playable.GetCurrentAnimatorClipInfoCount(layerIndex);
-
- public AnimatorClipInfo[] GetNextAnimatorClipInfo(int layerIndex = 0) => Playable.GetNextAnimatorClipInfo(layerIndex);
-
- public void GetNextAnimatorClipInfo(int layerIndex, List<AnimatorClipInfo> clips) => Playable.GetNextAnimatorClipInfo(layerIndex, clips);
-
- public int GetNextAnimatorClipInfoCount(int layerIndex = 0) => Playable.GetNextAnimatorClipInfoCount(layerIndex);
-
- #endregion
-
- #endregion
-
- }
- }
|