// 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);
}
}
/************************************************************************************************************************/
}
}