I’m using Root Motion Animation on a (rig-less) cube.
But my animations --even with “Animate Physics” turned on-- seem to ignore gravity.
When ever I jump (rb.AddForceAtPosition) while the Animator is in Idle state; my cube starts to float.
I found some posts explaining bugfixes like “GravityWeight” should be set to 1 by adding a ‘curve’ to the animation …but since I use a ‘custom’ Unity Animation, I cannot add a ‘curve’.
I also tried setting Animator.gravityWeight to 1 through script… but it seems a read-only function. And the result I ‘get’ from it is unsurprisingly: ‘0’.
I’m getting a bit desperate here, why isn’t my root animated cube using the gravity? And if GravityWeight is the true fix, how could I apply it to my (not imported) Unity Animation?
Just to register this here, it might help some people, and save a few hours of frustation:
Just some context:
root transform Y is baked into pose, Unity applies a
gravityWeight = 1 through the whole clip (that is case sensitive, minor g and capital W). That is on the documentation, but they don’t give the appropriate highlight to it. This only happens when root transform Y is baked.
So a lot of undesirable behavior comes from this when using root motion.
How to mix root motion AND script based motion:
MonoBehaviour have a method called
OnAnimatorMove(). You need to use this in a script attached to a
gameObject that have an Animator component. Basically, this method is called every time the animator WOULD apply a root motion (would, because it won’t anymore). When the animator finds this method in a script of that object, if no longer applies root motion, now you got to do it by script.
Note that the
Apply root motion parameter in the
Animator component is no longer a checkbox (bool), now it says “Handled by Script”.
So, what you got to do is this:
OnAnimatorMove(), you use the
Animator.deltaPosition property (that is the Vector 3 of the deltaPosition the root motion of the current WOULD have done at this frame) and you apply it to your
gameObject, plus whatever motion you want (like gravity).
So, this method will be the one that actually moves your
gameObject, using the root motion information as an input variable.
I need to test if one would also have to manually apply the rotation, but probably yes.
Also, note that the
OnAnimatorMove() runs in the Physics update, so you got to think around that when writing your thing.
I’m not completely sure that using the Animator’s physics makes sense considering what you’re trying to accomplish.
The animator’s root motion is meant to be used when having to do complex motions (i.e. non linear, nor uniformly accelerated). Moving a cube is a really simple thing and using an animator is definitely overkill.
A better solution would be to handle the cube’s movement through script directly.
Anyway, since we’re here, if you really want to use an animator for your movement you might want to check a few things out:
When using the animator’s physics, if you want to move the rigidbody you might need to handle some logic inside the OnAnimatorMove() method on a MonoBehaviour.
Learn about the StateMachineBehaviours
Regarding the “GravityWeight” parameter, you might need to uncheck the field Write Defaults on any State of the Animator that you don’t want to allow modifying your gravity.
Unfortunatey I can’t help you more since using the Root Motion on a non-rigged object is an approach that I’ve never used.