HybridAnimancerComponent.cs 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711
  1. // Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.Animations;
  5. using UnityEngine.Playables;
  6. namespace Animancer
  7. {
  8. /// <summary>[Pro-Only]
  9. /// A <see cref="NamedAnimancerComponent"/> which plays a main <see cref="RuntimeAnimatorController"/>
  10. /// with the ability to play other individual <see cref="AnimationClip"/>s separately.
  11. /// </summary>
  12. /// <remarks>
  13. /// <strong>Documentation:</strong>
  14. /// <see href="https://kybernetik.com.au/animancer/docs/manual/animator-controllers#hybrid">
  15. /// Hybrid</see>
  16. /// </remarks>
  17. /// https://kybernetik.com.au/animancer/api/Animancer/HybridAnimancerComponent
  18. ///
  19. [AddComponentMenu(Strings.MenuPrefix + "Hybrid Animancer Component")]
  20. [AnimancerHelpUrl(typeof(HybridAnimancerComponent))]
  21. public class HybridAnimancerComponent : NamedAnimancerComponent
  22. {
  23. /************************************************************************************************************************/
  24. #region Controller
  25. /************************************************************************************************************************/
  26. [SerializeField, Tooltip("The main Animator Controller that this object will play")]
  27. private ControllerTransition _Controller;
  28. /// <summary>[<see cref="SerializeField"/>]
  29. /// The transition containing the main <see cref="RuntimeAnimatorController"/> that this object plays.
  30. /// </summary>
  31. public ref ControllerTransition Controller => ref _Controller;
  32. /************************************************************************************************************************/
  33. /// <summary>
  34. /// Transitions to the <see cref="Controller"/> over its specified
  35. /// <see cref="Transition{TState}.FadeDuration"/> and returns the
  36. /// <see cref="Transition{TState}.State"/>.
  37. /// </summary>
  38. public ControllerState PlayController()
  39. {
  40. if (!_Controller.IsValid())
  41. return null;
  42. Play(_Controller);
  43. return _Controller.State;
  44. }
  45. /************************************************************************************************************************/
  46. /// <summary>The <see cref="Playable"/> of the <see cref="ControllerState"/>.</summary>
  47. public AnimatorControllerPlayable ControllerPlayable
  48. => _Controller.State.Playable;
  49. /************************************************************************************************************************/
  50. #endregion
  51. /************************************************************************************************************************/
  52. #region Initialization
  53. /************************************************************************************************************************/
  54. #if UNITY_EDITOR
  55. /// <summary>[Editor-Only]
  56. /// Sets <see cref="PlayAutomatically"/> = false by default so that <see cref="OnEnable"/> will play the
  57. /// <see cref="Controller"/> instead of the first animation in the
  58. /// <see cref="NamedAnimancerComponent.Animations"/> array.
  59. /// </summary>
  60. /// <remarks>
  61. /// Called by the Unity Editor when this component is first added (in Edit Mode) and whenever the Reset command
  62. /// is executed from its context menu.
  63. /// </remarks>
  64. protected override void Reset()
  65. {
  66. base.Reset();
  67. if (Animator != null)
  68. {
  69. Controller = Animator.runtimeAnimatorController;
  70. Animator.runtimeAnimatorController = null;
  71. }
  72. PlayAutomatically = false;
  73. }
  74. #endif
  75. /************************************************************************************************************************/
  76. /// <summary>
  77. /// Plays the <see cref="Controller"/> if <see cref="PlayAutomatically"/> is false (otherwise it plays the
  78. /// first animation in the <see cref="NamedAnimancerComponent.Animations"/> array).
  79. /// </summary>
  80. protected override void OnEnable()
  81. {
  82. if (!TryGetAnimator())
  83. return;
  84. PlayController();
  85. base.OnEnable();
  86. #if UNITY_ASSERTIONS
  87. if (Animator != null && Animator.runtimeAnimatorController != null)
  88. OptionalWarning.NativeControllerHybrid.Log($"An Animator Controller is assigned to the" +
  89. $" {nameof(Animator)} component while also using a {nameof(HybridAnimancerComponent)}." +
  90. $" Most likely only one of them is being used so the other should be removed." +
  91. $" See the documentation for more information: {Strings.DocsURLs.AnimatorControllers}", this);
  92. #endif
  93. }
  94. /************************************************************************************************************************/
  95. /// <summary>
  96. /// Sets <see cref="AnimancerGraph.KeepChildrenConnected"/> to <c>true</c> in order to avoid some
  97. /// undesirable behaviours caused by disconnecting <see cref="AnimatorControllerPlayable"/>s from the graph.
  98. /// </summary>
  99. protected override void OnInitializeGraph()
  100. {
  101. base.OnInitializeGraph();
  102. Graph.SetKeepChildrenConnected(true);
  103. }
  104. /************************************************************************************************************************/
  105. /// <inheritdoc/>
  106. public override void GatherAnimationClips(ICollection<AnimationClip> clips)
  107. {
  108. base.GatherAnimationClips(clips);
  109. clips.GatherFromSource(_Controller);
  110. }
  111. /************************************************************************************************************************/
  112. #endregion
  113. /************************************************************************************************************************/
  114. #region Animator Wrappers
  115. /************************************************************************************************************************/
  116. #region Properties
  117. /************************************************************************************************************************/
  118. /// <summary><see cref="AnimancerGraph.PlayableGraph"/></summary>
  119. public PlayableGraph playableGraph
  120. => Graph;
  121. /// <summary><see cref="Controller"/></summary>
  122. public RuntimeAnimatorController runtimeAnimatorController
  123. {
  124. get => Controller.Controller;
  125. set => Controller.Controller = value;
  126. }
  127. /************************************************************************************************************************/
  128. /// <summary>The <see cref="AnimancerNode.Speed"/> of the <see cref="Controller"/>.</summary>
  129. public float Speed
  130. {
  131. get => _Controller.State != null
  132. ? _Controller.State.Speed
  133. : _Controller.Speed;
  134. set
  135. {
  136. _Controller.Speed = value;
  137. if (_Controller.State != null)
  138. _Controller.State.Speed = value;
  139. }
  140. }
  141. /// <summary>Wraps the <see cref="Speed"/> property with the same name as <see cref="Animator.speed"/>.</summary>
  142. public float speed
  143. {
  144. get => Speed;
  145. set => Speed = value;
  146. }
  147. /************************************************************************************************************************/
  148. // Root Motion.
  149. /************************************************************************************************************************/
  150. /// <summary><see cref="Animator.applyRootMotion"/></summary>
  151. public bool applyRootMotion
  152. {
  153. get => Animator.applyRootMotion;
  154. set => Animator.applyRootMotion = value;
  155. }
  156. /// <summary><see cref="Animator.bodyRotation"/></summary>
  157. public Quaternion bodyRotation
  158. {
  159. get => Animator.bodyRotation;
  160. set => Animator.bodyRotation = value;
  161. }
  162. /// <summary><see cref="Animator.bodyPosition"/></summary>
  163. public Vector3 bodyPosition
  164. {
  165. get => Animator.bodyPosition;
  166. set => Animator.bodyPosition = value;
  167. }
  168. /// <summary><see cref="Animator.gravityWeight"/></summary>
  169. public float gravityWeight => Animator.gravityWeight;
  170. /// <summary><see cref="Animator.hasRootMotion"/></summary>
  171. public bool hasRootMotion => Animator.hasRootMotion;
  172. /// <summary><see cref="Animator.layersAffectMassCenter"/></summary>
  173. public bool layersAffectMassCenter
  174. {
  175. get => Animator.layersAffectMassCenter;
  176. set => Animator.layersAffectMassCenter = value;
  177. }
  178. /// <summary><see cref="Animator.pivotPosition"/></summary>
  179. public Vector3 pivotPosition => Animator.pivotPosition;
  180. /// <summary><see cref="Animator.pivotWeight"/></summary>
  181. public float pivotWeight => Animator.pivotWeight;
  182. /// <summary><see cref="Animator.rootRotation"/></summary>
  183. public Quaternion rootRotation
  184. {
  185. get => Animator.rootRotation;
  186. set => Animator.rootRotation = value;
  187. }
  188. /// <summary><see cref="Animator.rootPosition"/></summary>
  189. public Vector3 rootPosition
  190. {
  191. get => Animator.rootPosition;
  192. set => Animator.rootPosition = value;
  193. }
  194. /// <summary><see cref="Animator.angularVelocity"/></summary>
  195. public Vector3 angularVelocity => Animator.angularVelocity;
  196. /// <summary><see cref="Animator.velocity"/></summary>
  197. public Vector3 velocity => Animator.velocity;
  198. /// <summary><see cref="Animator.deltaRotation"/></summary>
  199. public Quaternion deltaRotation => Animator.deltaRotation;
  200. /// <summary><see cref="Animator.deltaPosition"/></summary>
  201. public Vector3 deltaPosition => Animator.deltaPosition;
  202. /// <summary><see cref="Animator.ApplyBuiltinRootMotion"/></summary>
  203. public void ApplyBuiltinRootMotion() => Animator.ApplyBuiltinRootMotion();
  204. /************************************************************************************************************************/
  205. // Feet.
  206. /************************************************************************************************************************/
  207. /// <summary><see cref="Animator.feetPivotActive"/></summary>
  208. public float feetPivotActive
  209. {
  210. get => Animator.feetPivotActive;
  211. set => Animator.feetPivotActive = value;
  212. }
  213. /// <summary><see cref="Animator.stabilizeFeet"/></summary>
  214. public bool stabilizeFeet
  215. {
  216. get => Animator.stabilizeFeet;
  217. set => Animator.stabilizeFeet = value;
  218. }
  219. /// <summary><see cref="Animator.rightFeetBottomHeight"/></summary>
  220. public float rightFeetBottomHeight => Animator.rightFeetBottomHeight;
  221. /// <summary><see cref="Animator.leftFeetBottomHeight"/></summary>
  222. public float leftFeetBottomHeight => Animator.leftFeetBottomHeight;
  223. /************************************************************************************************************************/
  224. #endregion
  225. /************************************************************************************************************************/
  226. #region Cross Fade
  227. /************************************************************************************************************************/
  228. /// <summary>Starts a transition from the current state to the specified state using normalized times.</summary>
  229. /// <remarks>If `fadeDuration` is negative, it uses the <see cref="AnimancerGraph.DefaultFadeDuration"/>.</remarks>
  230. public void CrossFade(
  231. int stateNameHash,
  232. float fadeDuration = ControllerState.DefaultFadeDuration,
  233. int layer = -1,
  234. float normalizedTime = float.NegativeInfinity)
  235. {
  236. fadeDuration = ControllerState.GetFadeDuration(fadeDuration);
  237. var controllerState = PlayController();
  238. controllerState.Playable.CrossFade(stateNameHash, fadeDuration, layer, normalizedTime);
  239. }
  240. /************************************************************************************************************************/
  241. /// <summary>Starts a transition from the current state to the specified state using normalized times.</summary>
  242. /// <remarks>If `fadeDuration` is negative, it uses the <see cref="AnimancerGraph.DefaultFadeDuration"/>.</remarks>
  243. public AnimancerState CrossFade(
  244. string stateName,
  245. float fadeDuration = ControllerState.DefaultFadeDuration,
  246. int layer = -1,
  247. float normalizedTime = float.NegativeInfinity)
  248. {
  249. fadeDuration = ControllerState.GetFadeDuration(fadeDuration);
  250. if (States.TryGet(stateName, out var state))
  251. {
  252. Play(state, fadeDuration);
  253. if (layer >= 0)
  254. state.LayerIndex = layer;
  255. if (normalizedTime != float.NegativeInfinity)
  256. state.NormalizedTime = normalizedTime;
  257. return state;
  258. }
  259. else
  260. {
  261. var controllerState = PlayController();
  262. controllerState.Playable.CrossFade(stateName, fadeDuration, layer, normalizedTime);
  263. return controllerState;
  264. }
  265. }
  266. /************************************************************************************************************************/
  267. /// <summary>Starts a transition from the current state to the specified state using times in seconds.</summary>
  268. /// <remarks>If `fadeDuration` is negative, it uses the <see cref="AnimancerGraph.DefaultFadeDuration"/>.</remarks>
  269. public void CrossFadeInFixedTime(
  270. int stateNameHash,
  271. float fadeDuration = ControllerState.DefaultFadeDuration,
  272. int layer = -1,
  273. float fixedTime = 0)
  274. {
  275. fadeDuration = ControllerState.GetFadeDuration(fadeDuration);
  276. var controllerState = PlayController();
  277. controllerState.Playable.CrossFadeInFixedTime(stateNameHash, fadeDuration, layer, fixedTime);
  278. }
  279. /************************************************************************************************************************/
  280. /// <summary>Starts a transition from the current state to the specified state using times in seconds.</summary>
  281. /// <remarks>If `fadeDuration` is negative, it uses the <see cref="AnimancerGraph.DefaultFadeDuration"/>.</remarks>
  282. public AnimancerState CrossFadeInFixedTime(
  283. string stateName,
  284. float fadeDuration = ControllerState.DefaultFadeDuration,
  285. int layer = -1,
  286. float fixedTime = 0)
  287. {
  288. fadeDuration = ControllerState.GetFadeDuration(fadeDuration);
  289. if (States.TryGet(stateName, out var state))
  290. {
  291. Play(state, fadeDuration);
  292. if (layer >= 0)
  293. state.LayerIndex = layer;
  294. state.Time = fixedTime;
  295. return state;
  296. }
  297. else
  298. {
  299. var controllerState = PlayController();
  300. controllerState.Playable.CrossFadeInFixedTime(stateName, fadeDuration, layer, fixedTime);
  301. return controllerState;
  302. }
  303. }
  304. /************************************************************************************************************************/
  305. #endregion
  306. /************************************************************************************************************************/
  307. #region Play
  308. /************************************************************************************************************************/
  309. /// <summary>Plays the specified state immediately, starting from a particular normalized time.</summary>
  310. public void Play(
  311. int stateNameHash,
  312. int layer = -1,
  313. float normalizedTime = float.NegativeInfinity)
  314. {
  315. var controllerState = PlayController();
  316. controllerState.Playable.Play(stateNameHash, layer, normalizedTime);
  317. }
  318. /************************************************************************************************************************/
  319. /// <summary>Plays the specified state immediately, starting from a particular normalized time.</summary>
  320. public AnimancerState Play(
  321. string stateName,
  322. int layer = -1,
  323. float normalizedTime = float.NegativeInfinity)
  324. {
  325. if (States.TryGet(stateName, out var state))
  326. {
  327. Play(state);
  328. if (layer >= 0)
  329. state.LayerIndex = layer;
  330. if (normalizedTime != float.NegativeInfinity)
  331. state.NormalizedTime = normalizedTime;
  332. return state;
  333. }
  334. else
  335. {
  336. var controllerState = PlayController();
  337. controllerState.Playable.Play(stateName, layer, normalizedTime);
  338. return controllerState;
  339. }
  340. }
  341. /************************************************************************************************************************/
  342. /// <summary>Plays the specified state immediately, starting from a particular time (in seconds).</summary>
  343. public void PlayInFixedTime(
  344. int stateNameHash,
  345. int layer = -1,
  346. float fixedTime = 0)
  347. {
  348. var controllerState = PlayController();
  349. controllerState.Playable.PlayInFixedTime(stateNameHash, layer, fixedTime);
  350. }
  351. /************************************************************************************************************************/
  352. /// <summary>Plays the specified state immediately, starting from a particular time (in seconds).</summary>
  353. public AnimancerState PlayInFixedTime(
  354. string stateName,
  355. int layer = -1,
  356. float fixedTime = 0)
  357. {
  358. if (States.TryGet(stateName, out var state))
  359. {
  360. Play(state);
  361. if (layer >= 0)
  362. state.LayerIndex = layer;
  363. state.Time = fixedTime;
  364. return state;
  365. }
  366. else
  367. {
  368. var controllerState = PlayController();
  369. controllerState.Playable.PlayInFixedTime(stateName, layer, fixedTime);
  370. return controllerState;
  371. }
  372. }
  373. /************************************************************************************************************************/
  374. #endregion
  375. /************************************************************************************************************************/
  376. #region Parameters
  377. /************************************************************************************************************************/
  378. /// <summary>Gets the value of the specified boolean parameter.</summary>
  379. public bool GetBool(int id) => ControllerPlayable.GetBool(id);
  380. /// <summary>Gets the value of the specified boolean parameter.</summary>
  381. public bool GetBool(string name) => ControllerPlayable.GetBool(name);
  382. /// <summary>Sets the value of the specified boolean parameter.</summary>
  383. public void SetBool(int id, bool value) => ControllerPlayable.SetBool(id, value);
  384. /// <summary>Sets the value of the specified boolean parameter.</summary>
  385. public void SetBool(string name, bool value) => ControllerPlayable.SetBool(name, value);
  386. /// <summary>Gets the value of the specified float parameter.</summary>
  387. public float GetFloat(int id) => ControllerPlayable.GetFloat(id);
  388. /// <summary>Gets the value of the specified float parameter.</summary>
  389. public float GetFloat(string name) => ControllerPlayable.GetFloat(name);
  390. /// <summary>Sets the value of the specified float parameter.</summary>
  391. public void SetFloat(int id, float value) => ControllerPlayable.SetFloat(id, value);
  392. /// <summary>Sets the value of the specified float parameter.</summary>
  393. public void SetFloat(string name, float value) => ControllerPlayable.SetFloat(name, value);
  394. /// <summary>Sets the value of the specified float parameter with smoothing.</summary>
  395. public float SetFloat(string name, float value, float dampTime, float deltaTime, float maxSpeed = float.PositiveInfinity)
  396. => _Controller.State.SetFloat(name, value, dampTime, deltaTime, maxSpeed);
  397. /// <summary>Sets the value of the specified float parameter with smoothing.</summary>
  398. public float SetFloat(int id, float value, float dampTime, float deltaTime, float maxSpeed = float.PositiveInfinity)
  399. => _Controller.State.SetFloat(id, value, dampTime, deltaTime, maxSpeed);
  400. /// <summary>Gets the value of the specified integer parameter.</summary>
  401. public int GetInteger(int id) => ControllerPlayable.GetInteger(id);
  402. /// <summary>Gets the value of the specified integer parameter.</summary>
  403. public int GetInteger(string name) => ControllerPlayable.GetInteger(name);
  404. /// <summary>Sets the value of the specified integer parameter.</summary>
  405. public void SetInteger(int id, int value) => ControllerPlayable.SetInteger(id, value);
  406. /// <summary>Sets the value of the specified integer parameter.</summary>
  407. public void SetInteger(string name, int value) => ControllerPlayable.SetInteger(name, value);
  408. /// <summary>Sets the specified trigger parameter to true.</summary>
  409. public void SetTrigger(int id) => ControllerPlayable.SetTrigger(id);
  410. /// <summary>Sets the specified trigger parameter to true.</summary>
  411. public void SetTrigger(string name) => ControllerPlayable.SetTrigger(name);
  412. /// <summary>Resets the specified trigger parameter to false.</summary>
  413. public void ResetTrigger(int id) => ControllerPlayable.ResetTrigger(id);
  414. /// <summary>Resets the specified trigger parameter to false.</summary>
  415. public void ResetTrigger(string name) => ControllerPlayable.ResetTrigger(name);
  416. /// <summary>Indicates whether the specified parameter is controlled by an <see cref="AnimationClip"/>.</summary>
  417. public bool IsParameterControlledByCurve(int id) => ControllerPlayable.IsParameterControlledByCurve(id);
  418. /// <summary>Indicates whether the specified parameter is controlled by an <see cref="AnimationClip"/>.</summary>
  419. public bool IsParameterControlledByCurve(string name) => ControllerPlayable.IsParameterControlledByCurve(name);
  420. /// <summary>Gets the details of one of the <see cref="Controller"/>'s parameters.</summary>
  421. public AnimatorControllerParameter GetParameter(int index) => ControllerPlayable.GetParameter(index);
  422. /// <summary>Gets the number of parameters in the <see cref="Controller"/>.</summary>
  423. public int GetParameterCount() => ControllerPlayable.GetParameterCount();
  424. /************************************************************************************************************************/
  425. /// <summary>The number of parameters in the <see cref="Controller"/>.</summary>
  426. public int parameterCount => ControllerPlayable.GetParameterCount();
  427. /// <summary>The parameters in the <see cref="Controller"/>.</summary>
  428. /// <remarks>
  429. /// This property allocates a new array when first accessed. To avoid that, you can use
  430. /// <see cref="GetParameterCount"/> and <see cref="GetParameter"/> instead.
  431. /// </remarks>
  432. public AnimatorControllerParameter[] parameters => _Controller.State.parameters;
  433. /************************************************************************************************************************/
  434. #endregion
  435. /************************************************************************************************************************/
  436. #region Other
  437. /************************************************************************************************************************/
  438. // Clips.
  439. /************************************************************************************************************************/
  440. /// <summary>Gets information about the <see cref="AnimationClip"/>s currently being played.</summary>
  441. public AnimatorClipInfo[] GetCurrentAnimatorClipInfo(int layerIndex = 0) => ControllerPlayable.GetCurrentAnimatorClipInfo(layerIndex);
  442. /// <summary>Gets information about the <see cref="AnimationClip"/>s currently being played.</summary>
  443. public void GetCurrentAnimatorClipInfo(int layerIndex, List<AnimatorClipInfo> clips) => ControllerPlayable.GetCurrentAnimatorClipInfo(layerIndex, clips);
  444. /// <summary>Gets the number of <see cref="AnimationClip"/>s currently being played.</summary>
  445. public int GetCurrentAnimatorClipInfoCount(int layerIndex = 0) => ControllerPlayable.GetCurrentAnimatorClipInfoCount(layerIndex);
  446. /// <summary>Gets information about the <see cref="AnimationClip"/>s currently being transitioned towards.</summary>
  447. public AnimatorClipInfo[] GetNextAnimatorClipInfo(int layerIndex = 0) => ControllerPlayable.GetNextAnimatorClipInfo(layerIndex);
  448. /// <summary>Gets information about the <see cref="AnimationClip"/>s currently being transitioned towards.</summary>
  449. public void GetNextAnimatorClipInfo(int layerIndex, List<AnimatorClipInfo> clips) => ControllerPlayable.GetNextAnimatorClipInfo(layerIndex, clips);
  450. /// <summary>Gets the number of <see cref="AnimationClip"/>s currently being transitioned towards.</summary>
  451. public int GetNextAnimatorClipInfoCount(int layerIndex = 0) => ControllerPlayable.GetNextAnimatorClipInfoCount(layerIndex);
  452. /************************************************************************************************************************/
  453. // Humanoid.
  454. /************************************************************************************************************************/
  455. /// <summary><see cref="Animator.humanScale"/></summary>
  456. public float humanScale => Animator.humanScale;
  457. /// <summary><see cref="Animator.isHuman"/></summary>
  458. public bool isHuman => Animator.isHuman;
  459. /// <summary><see cref="Animator.GetBoneTransform"/></summary>
  460. public Transform GetBoneTransform(HumanBodyBones humanBoneId) => Animator.GetBoneTransform(humanBoneId);
  461. /// <summary><see cref="Animator.SetBoneLocalRotation"/></summary>
  462. public void SetBoneLocalRotation(HumanBodyBones humanBoneId, Quaternion rotation) => Animator.SetBoneLocalRotation(humanBoneId, rotation);
  463. /************************************************************************************************************************/
  464. // Layers.
  465. /************************************************************************************************************************/
  466. /// <summary>Gets the number of layers in the <see cref="Controller"/>.</summary>
  467. public int GetLayerCount() => ControllerPlayable.GetLayerCount();
  468. /// <summary>The number of layers in the <see cref="Controller"/>.</summary>
  469. public int layerCount => ControllerPlayable.GetLayerCount();
  470. /// <summary>Gets the index of the layer with the specified name.</summary>
  471. public int GetLayerIndex(string layerName) => ControllerPlayable.GetLayerIndex(layerName);
  472. /// <summary>Gets the name of the layer with the specified index.</summary>
  473. public string GetLayerName(int layerIndex) => ControllerPlayable.GetLayerName(layerIndex);
  474. /// <summary>Gets the weight of the layer at the specified index.</summary>
  475. public float GetLayerWeight(int layerIndex) => ControllerPlayable.GetLayerWeight(layerIndex);
  476. /// <summary>Sets the weight of the layer at the specified index.</summary>
  477. public void SetLayerWeight(int layerIndex, float weight) => ControllerPlayable.SetLayerWeight(layerIndex, weight);
  478. /************************************************************************************************************************/
  479. // StateMachineBehaviours.
  480. /************************************************************************************************************************/
  481. /// <summary><see cref="Animator.GetBehaviour{T}()"/></summary>
  482. public T GetBehaviour<T>() where T : StateMachineBehaviour => Animator.GetBehaviour<T>();
  483. /// <summary><see cref="Animator.GetBehaviours{T}()"/></summary>
  484. public T[] GetBehaviours<T>() where T : StateMachineBehaviour => Animator.GetBehaviours<T>();
  485. /// <summary><see cref="Animator.GetBehaviours"/></summary>
  486. public StateMachineBehaviour[] GetBehaviours(int fullPathHash, int layerIndex) => Animator.GetBehaviours(fullPathHash, layerIndex);
  487. /************************************************************************************************************************/
  488. // States.
  489. /************************************************************************************************************************/
  490. /// <summary>Returns information about the current state.</summary>
  491. public AnimatorStateInfo GetCurrentAnimatorStateInfo(int layerIndex = 0) => ControllerPlayable.GetCurrentAnimatorStateInfo(layerIndex);
  492. /// <summary>Returns information about the next state being transitioned towards.</summary>
  493. public AnimatorStateInfo GetNextAnimatorStateInfo(int layerIndex = 0) => ControllerPlayable.GetNextAnimatorStateInfo(layerIndex);
  494. /// <summary>Indicates whether the specified layer contains the specified state.</summary>
  495. public bool HasState(int layerIndex, int stateID) => ControllerPlayable.HasState(layerIndex, stateID);
  496. /************************************************************************************************************************/
  497. // Transitions.
  498. /************************************************************************************************************************/
  499. /// <summary>Indicates whether the specified layer is currently executing a transition.</summary>
  500. public bool IsInTransition(int layerIndex = 0) => ControllerPlayable.IsInTransition(layerIndex);
  501. /// <summary>Gets information about the current transition.</summary>
  502. public AnimatorTransitionInfo GetAnimatorTransitionInfo(int layerIndex = 0) => ControllerPlayable.GetAnimatorTransitionInfo(layerIndex);
  503. /************************************************************************************************************************/
  504. // Other.
  505. /************************************************************************************************************************/
  506. /// <summary><see cref="Animator.avatar"/></summary>
  507. public Avatar avatar
  508. {
  509. get => Animator.avatar;
  510. set => Animator.avatar = value;
  511. }
  512. /// <summary><see cref="Animator.cullingMode"/></summary>
  513. public AnimatorCullingMode cullingMode
  514. {
  515. get => Animator.cullingMode;
  516. set => Animator.cullingMode = value;
  517. }
  518. /// <summary><see cref="Animator.fireEvents"/></summary>
  519. public bool fireEvents
  520. {
  521. get => Animator.fireEvents;
  522. set => Animator.fireEvents = value;
  523. }
  524. /// <summary><see cref="Animator.hasBoundPlayables"/></summary>
  525. public bool hasBoundPlayables => Animator.hasBoundPlayables;
  526. /// <summary><see cref="Animator.hasTransformHierarchy"/></summary>
  527. public bool hasTransformHierarchy => Animator.hasTransformHierarchy;
  528. /// <summary><see cref="Animator.isInitialized"/></summary>
  529. public bool isInitialized => Animator.isInitialized;
  530. /// <summary><see cref="Animator.isOptimizable"/></summary>
  531. public bool isOptimizable => Animator.isOptimizable;
  532. /// <summary><see cref="Animator.logWarnings"/></summary>
  533. public bool logWarnings
  534. {
  535. get => Animator.logWarnings;
  536. set => Animator.logWarnings = value;
  537. }
  538. /// <summary><see cref="Animator.updateMode"/></summary>
  539. /// <remarks>Changing this at runtime doesn't work when using the Playables API.</remarks>
  540. public AnimatorUpdateMode updateMode
  541. {
  542. get => Animator.updateMode;
  543. set => Animator.updateMode = value;
  544. }
  545. /************************************************************************************************************************/
  546. /// <summary><see cref="Animator.keepAnimatorStateOnDisable"/></summary>
  547. public bool keepAnimatorStateOnDisable
  548. {
  549. get => Animator.keepAnimatorStateOnDisable;
  550. set => Animator.keepAnimatorStateOnDisable = value;
  551. }
  552. /************************************************************************************************************************/
  553. /// <summary><see cref="Animator.Rebind"/></summary>
  554. public void Rebind() => Animator.Rebind();
  555. /************************************************************************************************************************/
  556. #endregion
  557. /************************************************************************************************************************/
  558. #endregion
  559. /************************************************************************************************************************/
  560. }
  561. /// <summary>Extension methods for <see cref="HybridAnimancerComponent"/>.</summary>
  562. /// https://kybernetik.com.au/animancer/api/Animancer/HybridAnimancerComponentExtensions
  563. ///
  564. public static class HybridAnimancerComponentExtensions
  565. {
  566. /************************************************************************************************************************/
  567. /// <summary>
  568. /// Advances time by the specified value (in seconds)
  569. /// and immediately applies the current states of all animations to the animated objects.
  570. /// </summary>
  571. /// <remarks>
  572. /// This is an extension method to avoid being treated as a <see cref="MonoBehaviour"/>
  573. /// <code>Update</code> message and getting called every frame.
  574. /// </remarks>
  575. public static void Update(this HybridAnimancerComponent animancer, float deltaTime)
  576. => animancer.Evaluate(deltaTime);
  577. /************************************************************************************************************************/
  578. }
  579. }