47 lines
1.8 KiB
C#
47 lines
1.8 KiB
C#
using UnityEngine;
|
|
|
|
namespace VOID.Generic.Objects.Unit.Animations
|
|
{
|
|
/// <summary>
|
|
/// Little hacky trick to make traversal root motion animation ALWAYS move by identical distance.
|
|
///
|
|
/// Requirements:
|
|
/// 1. Attach this to start/loop/end states in animator
|
|
/// 2. Transitions should have as small as possible exit time, less than 0.1 (0.0 would be best)
|
|
/// </summary>
|
|
public class MatchTargetTraversalStateHelper : StateMachineBehaviour
|
|
{
|
|
private bool _didMatchTarget;
|
|
private Vector3 _startPosition;
|
|
|
|
public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
|
|
{
|
|
_didMatchTarget = false;
|
|
_startPosition = animator.transform.position;
|
|
}
|
|
|
|
public override void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
|
|
{
|
|
if (animator.GetCurrentAnimatorStateInfo(layerIndex).fullPathHash != stateInfo.fullPathHash) return;
|
|
if (_didMatchTarget) return;
|
|
|
|
_didMatchTarget = true;
|
|
var clip = animator.GetCurrentAnimatorClipInfo(layerIndex)[0].clip;
|
|
var clipOffset = animator.transform.TransformDirection(clip.length * clip.averageSpeed);
|
|
var repeat = clip.isLooping ? 100 : 1;
|
|
animator.MatchTarget(
|
|
_startPosition + clipOffset*repeat,
|
|
Quaternion.identity,
|
|
AvatarTarget.Root,
|
|
new MatchTargetWeightMask(Vector3.one, 0),
|
|
stateInfo.normalizedTime,
|
|
repeat
|
|
);
|
|
}
|
|
|
|
public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
|
|
{
|
|
animator.InterruptMatchTarget(false);
|
|
}
|
|
}
|
|
} |