How to move kinematic rigid body in addition to animator state.

I have the following setup:

  1. a kinematic rigidbody (which btw, doesn’t have a collider nor mesh – I’m only using it to establish a joint between it and a child rigid body / collider / mesh representing the visible game object in my scene).
  2. An animator component attached to this rigid body. The animator controller has a single default state, with an animation clip recorded via the animation window; it’s a bobbing / sinusoidal motion along the Y axis.
  3. A “player input” script which, on FixedUpdate basically gets the vertical axis and does something along the lines of: transform.position = transform.forward * 5f * verticalAxisValue

So the idea is:

  1. The rigidbody is kinematic, so I can translate it via its transform.
  2. Again, the rigidbody is kinematic, so it should also be ok to animate it via curves.

But the problem is that, the minute I enable that animator, the bobbing animation plays and it seems to completely override my attempt at manually setting the transform via code (step 3 above). That is, if the animator is playing, any attempts to additionally further modify the transform in code are ignored, regardless of the animator’s update mode or root motion option.

The one workaround I found so far is to enclose the above setup in an empty parent, and instead apply the programatic transform changes (step 3) to the empty, so that I translate that transform, while the rigid body animates according to the animator state within its local space. But I’m wondering if there is a way to do this without the extra empty?

I also tried creating 2 animator layers, leaving the base one with no states, while putting the bobbing state in the second one and giving it a weight of .5 and blend mode of additive. I was hopping this would “add” the animation to any programatic transform changes, but it didn’t work.

Also, kind of related, I’d assume the animator clip is modifying the transform / rigid body in local space, relative to the empty parent, but if I rotate the parent, the animation seems to still apply to global Y, regardless of the rigid body having globally rotated as a consequence of it being dependent on its parent’s coordinate space.

The problem you’ve gotten yourself into might be that you first recorded your animation and then corrected the setup. You most likely animated the “position” of your object first, not your “localposition”. If you do that it should move relative to it’s parent.

Based on what I read here: http://forum.unity3d.com/threads/playing-animation-local-to-position-in-unity.53832/ I’m adding another solution to the one proposed by hexagonius.

You can add your transformations to the values already set by the animator in LateUpdate.

That is:

     // rest of your class...
     void FixedUpdate() {
       this.PositionFromPlayerInput = <physics stuff, Time.deltaTime, etc...>
      }

      void LateUpdate() {
        this.transform.position = this.transform.rotation * this.transform.position;
        this.transform.position += this.PositionFromPlayerInput;
      }

     // rest of your class...

For the above to work though, you have to make sure that when you initially animate your body it’s centered in world space (or an empty); otherwise you’d already have an implicit offset in your transform.

I’m going to go for this second approach because I’m also trying for the translation to the rigid body to affect a child rigid body of it which is attached thru a spring. But otherwise both solutions work.