using UnityEngine;
namespace ECM2
{
///
///
/// RootMotionController.
///
/// Helper component to get Animator root motion velocity vector (animRootMotionVelocity).
///
/// This must be attached to a game object with an Animator component.
///
[RequireComponent(typeof(Animator))]
public class RootMotionController : MonoBehaviour
{
#region FIELDS
protected Animator _animator;
protected Vector3 _rootMotionDeltaPosition;
protected Quaternion _rootMotionDeltaRotation;
#endregion
#region METHOD
///
/// Flush any accumulated deltas. This prevents accumulation while character is toggling root motion.
///
public virtual void FlushAccumulatedDeltas()
{
_rootMotionDeltaPosition = Vector3.zero;
_rootMotionDeltaRotation = Quaternion.identity;
}
///
/// Return current root motion rotation and clears accumulated delta rotation.
///
public virtual Quaternion ConsumeRootMotionRotation()
{
Quaternion rootMotionRotation = _rootMotionDeltaRotation;
_rootMotionDeltaRotation = Quaternion.identity;
return rootMotionRotation;
}
///
/// Get the calculated root motion velocity.
///
public virtual Vector3 GetRootMotionVelocity(float deltaTime)
{
if (deltaTime == 0.0f)
return Vector3.zero;
Vector3 rootMotionVelocity = _rootMotionDeltaPosition / deltaTime;
return rootMotionVelocity;
}
///
/// Return current root motion velocity and clears accumulated delta positions.
///
public virtual Vector3 ConsumeRootMotionVelocity(float deltaTime)
{
Vector3 rootMotionVelocity = GetRootMotionVelocity(deltaTime);
_rootMotionDeltaPosition = Vector3.zero;
return rootMotionVelocity;
}
#endregion
#region MONOBEHAVIOUR
///
/// If overriden, base method MUST be called.
///
public virtual void Awake()
{
_animator = GetComponent();
if (_animator == null)
{
Debug.LogError($"RootMotionController: There is no 'Animator' attached to the '{name}' game object.\n" +
$"Please attach a 'Animator' to the '{name}' game object");
}
}
///
/// If overriden, base method MUST be called.
///
public virtual void Start()
{
_rootMotionDeltaPosition = Vector3.zero;
_rootMotionDeltaRotation = Quaternion.identity;
}
///
/// If overriden, base method MUST be called.
///
public virtual void OnAnimatorMove()
{
// Accumulate root motion deltas between character updates
_rootMotionDeltaPosition += _animator.deltaPosition;
_rootMotionDeltaRotation = _animator.deltaRotation * _rootMotionDeltaRotation;
}
#endregion
}
}