// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik // using UnityEngine; namespace Animancer { /// /// A component which takes the root motion from an /// and applies it to a different object. /// /// /// /// This can be useful if the character's or is on a /// parent of the to keep the model separate from the logical components. /// /// Documentation: /// /// Redirecting Root Motion /// /// /// https://kybernetik.com.au/animancer/api/Animancer/RedirectRootMotion /// [HelpURL("https://kybernetik.com.au/animancer/api/Animancer/" + nameof(RedirectRootMotion))] [RequireComponent(typeof(Animator))] public abstract class RedirectRootMotion : MonoBehaviour { /************************************************************************************************************************/ [SerializeField] [Tooltip("The Animator which provides the root motion")] private Animator _Animator; /// The which provides the root motion. public ref Animator Animator => ref _Animator; /************************************************************************************************************************/ /// The current position of the target. public abstract Vector3 Position { get; set; } /// The current rotation of the target. public abstract Quaternion Rotation { get; set; } /************************************************************************************************************************/ /// Is enabled? public virtual bool ApplyRootMotion => Animator != null; /************************************************************************************************************************/ /// Automatically finds the . protected virtual void OnValidate() { TryGetComponent(out _Animator); } /************************************************************************************************************************/ /// Applies the root motion from the to the . protected virtual void OnAnimatorMove() { if (!ApplyRootMotion) return; Position += Animator.deltaPosition; Rotation *= Animator.deltaRotation; } /************************************************************************************************************************/ } /// A with a generic . /// https://kybernetik.com.au/animancer/api/Animancer/RedirectRootMotion_1 /// [HelpURL("https://kybernetik.com.au/animancer/api/Animancer/" + nameof(RedirectRootMotion) + "_1")] public abstract class RedirectRootMotion : RedirectRootMotion where T : Object { /************************************************************************************************************************/ [SerializeField] [Tooltip("The object which the root motion will be applied to")] private T _Target; /// The object which the root motion will be applied to. public ref T Target => ref _Target; /************************************************************************************************************************/ /// /// Returns true if the and are set and /// is enabled. /// public override bool ApplyRootMotion => Target != null && base.ApplyRootMotion; /************************************************************************************************************************/ /// Automatically finds the and . protected override void OnValidate() { base.OnValidate(); if (_Target == null) { var parent = transform.parent; if (parent != null) _Target = parent.GetComponentInParent(); if (_Target == null) TryGetComponent(out _Target); } } /************************************************************************************************************************/ } }