- Home /
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.
Did you ever figure this out? I'm also getting precision errors, usually from 0.002 to 0.004 from where its supposed to be.
Answer by pierrepaul · Jul 22, 2013 at 12:22 PM
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
hi pierre paul,
What I have is a general system, hence the code, but a specific example is a jump between platforms. I want the character to end up at a location for the jump and I am using target matching to smooth the animation between the time the feet leave the old platform and the feet reach the new one. So basically as you describe.
But as I mention if I call this (and don’t do an interrupt), it doesn’t seem to target match to that exact point. It gets close, but far enough away to be wrong and noticeable.
I am also definitely not seeing the behaviour you indicate that Interrupt$$anonymous$$atchTarget will do. If I call Interrupt once with the TRUE argument, it does not end up at the end target match position at all.
I found I actually had to set the target match and interrupt every single update while the animation played to get it to get really close to the final position (still not perfect, but so close now it looks right).
That fact above leads me to believe there is a precision error (Since its better the smaller the distance to go) or something else interfering but I am not sure what would stop mecanim from doing the root motion precisely.
Hi.
An error that I often see is that $$anonymous$$atchTarget is active while being in a Transition.
For instance, when you have an m_Target$$anonymous$$atchingStopTime that is set to 0.9 but you have a transition that starts at 0.7, the results will be undefined.
will have clear warning when this happens.
Otherwise, please log a bug with the bare-bone simplified scene and I will take a look at it.
thanks!
pp
Ahh ok I will check for that, I just need to check the IsInTransition on the Animator correct? If that doesnt fix it I will come up with a simple scene and send it to you. Thanks for the help :)
Answer by TonyLi · Jul 29, 2013 at 02:48 PM
Have you tried Unity 4.2? The release notes say that several IK precision bugs have been fixed.
Your answer
Follow this Question
Related Questions
Is it possible to change root motion animations to in place? 3 Answers
Using root motion scripting for specific animations 1 Answer
Mecanim: Bake Only Z Root Motion Into Pose 0 Answers
why Do my animations behave differently ? 0 Answers
How to respect colliders in Animations with Root Motion ? 1 Answer