Files
2026-07-09 21:33:33 +02:00

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