- Home /
Child animator component is moving parent despite unchecking "Apply Root Motion"
I have a child object. The child object has an animator. I set "Apply Root Motion" on the animator to false. Regardless, the animator still changes the position and rotation of the parent object. Does anyone have a solution or an explanation to this problem?
Edit: The parent object has a RigidBody component and the animated child object has a collider within it's own hierarchy. When the animation moves the bone with the collider object, it changes the center of mass, and other fields in the RigidBody "info" tab. It seems like this is causing the parent object to move and rotate. I tried zeroing out these field in code, but not all of them are exposed and some of them yield errors when I do that. Is there any way to stop my parent object from moving/rotating along with this child?
Answer by nicholascarrow · Sep 23, 2021 at 08:13 PM
So the answer, apparently, is that you can't fix this. This thread, in which someone with a similar setup is experiencing the same problem, elaborates on why. In short, if you have collider(s) in child object(s) that move or rotate for any reason, whether that be script or animation, they are subject to changing the position and rotation of the root object. This means that the common advice of setting up animator objects as children in order to safely and precisely move them contains an asterisk: you can't trust that the true position (or rotation) of your object will be exactly where you expect (at least if you expect to set up any collision in the bones of your animator object).
One scenario where this might cause problems is if you use raycasting in order to keep your characters grounded. This is useful if you want to allow your characters to move on slopes, or if you want to change the direction of gravity in your levels. Using this setup, you might decide to snap your character position to an offset of your raycast hit point, in the direction of it's hit normal, based on the height of your character, so that your characters feet will always remain properly grounded.
This is where the problem comes in. The most reasonable origin for your raycast would be your character's origin (or at least some offset of this). If the origin of your root object is constantly moving because of the way your character is animated, such an approach will lead to your grounding logic causing your character to slide across the floor. This problem will also occur if your raycast direction is based on your character's down direction, and your character's rotation is constantly changing because of the way it is animated.
Now, most idle animations that remain sufficiently in place do not seem to cause this problem, and animations that convey movement (like running and jumping) will usually be fine too, particularly if you animate them in place in your animation software, but also because the sliding will likely not be noticeable compared to your scripted actual character movement. However, if you use an animation that does substantially move your character, but you want to keep their game object in the same place (imagine a get-up animation where your character moves from lying on the floor to standing), you will run into the sliding problem.
While there doesn't appear to be a fix for this (other than removing all collision from your character's bones and using a giant capsule collider, which would be fine for games where you don't need collision accuracy), there is a workaround, at least for the scenario I described. If you want your character object to remain in place, and you are using the raycasting method of keeping it grounded, you can do this to avoid the sliding problem: Based on your needs, you can either simply suspend your grounding logic and disable all other movement/physics during the problematic animation, or you can create a new transform, initialize it's position/rotation to be the same as your character object, set it as a child of whatever platform your character object is standing on, and use that to set your character position/rotation for the duration of the problematic animation (this will account for things like moving platforms). If you create a new transform, you'll still have to suspend your grounding logic, or you can just use position/direction data from the new transform to override your grounding logic (the latter option is actually more robust in some really niche use-cases than just setting the position/rotation outright).