Target Matching in Mecanim not being accurate

Hey everyone,

I am using mecanim for our character movement and am trying to fix several precision errors with our animations. I have been searching the site and the internet all day for solutions but everything I have read and tried hasn’t worked.

I am using OnAnimatorMove and using the exact root position/rotation there:

transform.position = m_Animator.rootPosition;
transform.rotation = m_Animator.rootRotation;

I tried to use target matching to ensure our characters end up in the exact right position, however I have had no luck getting this to go to the exact position I give it. The code for the target matching is:

if (!m_bAnimatonStarted)
{
	AnimatorStateInfo currentState = m_Animator.GetCurrentAnimatorStateInfo(0);
						
	if (currentState.IsName(GetAnimationStateName()))
	{	
		m_bAnimatonStarted = true;
		m_Animator.MatchTarget(m_TargetMatchingTransform.position, m_TargetMatchingTransform.rotation, AvatarTarget.Root, new MatchTargetWeightMask(Vector3.one, 0.0f), m_TargetMatchingStartTime, m_TargetMatchingEndTime);

The character does attempt to do the target matching but the end result is that it isnt correctly on the final animation point. The differences in position arent massive, when I query the Animator.targetPosition and what my target match position should be at the end, it is a difference of 0.14, -0.05, -0.36. But its enough to cause the whole thing to not line up right and look wrong.

I got it a whole lot closer by doing the following hacky code in every update as the animation I wanted played.

m_Animator.MatchTarget(m_TargetMatchingTransform.position, m_TargetMatchingTransform.rotation, m_TargetMatchingPart, new MatchTargetWeightMask(Vector3.one, 0.0f), m_TargetMatchingStartTime, m_TargetMatchingEndTime);
m_Animator.InterruptMatchTarget(true);

For whatever reason this seems to get the end result a lot closer, almost correct.
This sounds like to me that there is some kind of either external factor or precision error which makes it less accurate the further out it is.

Note that if I remove the InteruptMatchTarget call and just MatchTarget each frame, it ends up as far away as it used to be. (IE same result as just calling it at the start)

My characters do have a nav mesh agent and a character controller, but both are disabled as I do this animation. The animation has some movement without the target matching, but doesnt move after the end point. I did do test by setting the end time to 1.0 but it still doesnt match up.

Does anyone have any tips for what might be wrong and what else I can try.

Thanks for all help in advance.

Let me know if theres any more information I can provide.

I can’t shake the feeling there is some offset or something else I am missing.

Hi MatchTarget should be used to smoothly modify the root motion of the character during a certain time interval - m_TargetMatchingStartTime->m_TargetMatchingStopTime in your case.

An example of this is when you want a character to jump on platforms that have different heights, you would want to start matchTarget (m_TargetMatchingStartTime) when the feet leave the floor and stop it (m_TargetMatchingStopTime) when the feet reaches the floor.

Internally what Mecanim does is look at the animation at both those times, and handles matching the root animation smoothly…

When you call InterruptMatchTarget with TRUE for argument you tell the system to stop matching the target and directly “go” to the desired position.

Does that make sense ? your code is missing start-stop time so I’m not really sure what you are trying to do…

I you simply want to directly go to a position, do that in the OnAnimatorMove()

transform.position = GetDesiredPosition(); // your own code.
transform.rotation = GetDesiredRotation(); // your own code

m_Animator.rootPosition = transform.position;
m_Animator.rootRotation = transform.rotation;

hopes this help

pp

Have you tried Unity 4.2? The release notes say that several IK precision bugs have been fixed.