Combining Physics and Animation in Unity

Working with animations is easy in Unity, and so is working with physics. However when you combine those two, things can go haywire. I wanted to write a short post about it and how to avoid some of the potential pitfalls.

If TL;DR: scroll down and read the summarum and check out the Unity webplayer demonstration.

Understanding Time in Unity

It’s a fundamental thing to understand how time works in Unity. In one hand you have the regular, variable time step update loop which is governed by the rendering, and on the other hand you have the physics, fixed time step update loop which is governed by the physics engine. Because of their nature, they’re never quite in sync. This means that there are basically two instances of the same universe but in different time!

From regular world to physics world

By default the animations are updated in the regular update loop. This is perfectly fine, and gives us smooth visual results. However, because the time in physics world is different, objects updated in the regular update loop appear to move erratically in the physics world. If you’ve ever animated a collider and placed some physics objects on top of it, you might know what this means. physicsanimation_inspectorLuckily this can be solved by forcing the animation to be updated in the physics loop – just use the Animate Physics setting in either Animator or Animation component.

The caveat with this is that once you go from the regular update to the physics update, you will start to get small jitter in the motion as the physics is never perfectly in sync with regular update. Again, luckily this can be solved with interpolation modes (see below).

Moving versus Reappearing

Once you set the animation to update in the physics loop, the physics engine sees the collider being updated at regular intervals. At every frame, the collider’s position is updated as dictated by the animation. That’s all we need, right? Unfortunately this doesn’t mean that the physics sees the collider moving. In fact, what the physics engine just sees is a collider without a rigidbody disappearing from somewhere, and appearing at someplace else! In physics perspective, the collider doesn’t have any movement speed, and it’s not moving in any direction. This will cause some issues.

First, because the collider is disappearing and appearing, there’s a great probability that the new position of the collider is actually intersecting with some of the rigidbodies in the world, causing erratic collisions and potential fall-throughs.

Secondly, if the animated collider is moving underneath some rigidbodies, there is no friction at play at all. This means that collider is simply sliding under those rigidbodies on top of it, leaving them be.

So how to fix it? Simple. Just add a rigidbody to the animated collider and you’re set. This ensures that the collider has a proper physical response. Remember to set it to kinematic!

Getting Really Out of Sync!

It’s a noble goal to have your update loop and fixed update loop are running somewhat at the same pace (say, 60Hz) – everything looks smooth and jitter-free. But when your update loop  rate is nothing near a multiple of the fixed update loop rate, you start to see sync problems.

Quick example: let’s say your regular update is running about 45 FPS (22.22ms delta time) while you have set the physics to run at 60 Hz (16.66ms delta time).  This means that roughly for every 3 regular updates there will be 4 physics updates. And because there can be only integer number of physics updates per frame, this means that two of the frames will have 1 physics update and one will have 2 updates.  It gets even worse with 40 FPS regular update rate and 60 Hz physics update rate (why?)

On the other hand, if you lower your physics update rate to something like 10 Hz (which you really should, just to test your game physics), you get opposite effect. There will be frames where physics is not updated at all. If you rely on the fact that FixedUpdate gets called every frame just because your FPS is lower than your physics update rate, don’t! Bugs are known to exists because of that 🙂

Past or future?

physicsanimation_interpolationWhile these settings fix the physics side of things, the physics animation is more or less  out of sync from the visual representation every frame. For this Unity offers a way to interpolate the position of rigidbody for the regular update. There are two modes: interpolation and extrapolation. (The interpolation mode is not only for animation, it works with any rigidbody)

Interpolation means that the position for the object is calculated by taking the current update time, and moving it backwards one physics update delta time. Now there are at least two physics updates: one behind the chosen time and one ahead. Unity simply interpolates between those two updates to conceive a position which it then uses for the update position. This means that the interpolation is actually lagging behind one physics update! But it’s guaranteed to be rather smooth.

The other option is to use extrapolation. Instead of using those two physics updates and interpolate between them, Unity uses them to predict the future position for the object. While this doesn’t suffer from a lag, it’s unfortunately unable to see in the future correctly, causing a visual jitter when the prediction fails. And it will fail often, especially in sudden changes in motion (like collisions…)

Summarum

Here are my recipe for solid physics-compatible animation in Unity:

  • Add rigidbody to the animated collider for proper physics response and set it kinematic because of the animations (thanks T.M)
  • Set the animation to run in the physics update (Animate Physics)
  • Use interpolation for smooth visuals if needed
  • Aim for same (or integer multiple) regular update and physics update rates where possible (i.e. 60Hz or 30FPS/60Hz etc)

Demonstration

I’ve created a small Unity webplayer demonstration to easy testing how these settings affect the physics stability.

You can check it out here (http://sampsy.com/blog/physicsanimation.html)

There is a simple setup with a cube, a sphere and an animated platform. With the UI you can setup various things for the platform.

Be sure to test out all the settings and their combinations. Try these:

  • No rigidbody, with or without physics animation (default settings). Objects stay in place, platform sliding beneath. When the platform rises, sphere simply goes through it.
  • With rigidbody but no physics animation: The cube stays properly on the platform, but jitters noticeably. With 10Hz physics the cube gets really wonky.
  • With rigidbody and physics animation: The cube stays on the platform as expected, sphere rolls and falls as expected. Works well even in 10Hz physics rate!
  • No rigidbody, fast animation, 10Hz physics rate: Objects simply fall immediately through the platform as it moves into them.
  • (Also test out the interpolation modes for the platform)

That’s it. If you have any feedback, leave it here or in twitter (@snlehton).

13 thoughts on “Combining Physics and Animation in Unity”

  1. Your posts about physics were very helpful!! Thank you.

    Im an intern at a small game development company in Portugal, and I have been learning Unity on the last months.

    Hope to see more posts from you! 🙂

  2. Oh, i forgot to ask you one thing! 🙂

    When making 2d games, should I use animations for the enemies movements, or should all the movement be carried through code (changing transform.position) ? In the past, I had problems using animation for enemy movement and patterns, because animations always played on root coordiantes (I had to use a parent GO to change position and have root elements on local 000). Also, i had problems with physics, but I think that would be due to not using a rigidbody on the enemy, I will try to do that again, after reading your posts.

    Once more, thank you for your help!

    1. Hi and thanks for the comment (and sorry for not replying sooner).

      I’d definitely move things using code. Just give the rigidbody some velocity. I prefer lerping the velocity to the target velocity. Check out my slides about Physics gameplay (https://grovecodeblog.wordpress.com/2013/10/13/unity-physics-gameplay/)

      I have just little experience of using root motion, and while it is a great concept, it seems to be quite hard to get right (i.e. making sure that the character moves as expected and that animation blending is done correctly etc)

  3. Any chance you’d be willing to post the Unity project? I’m having no luck getting stable physics with these settings.

    1. Well nevermind. Even after reading the article twice and the summary any number of times, I found the missing piece of the puzzle. Turn on “Is Kinematic”. You may want to add that to the Summarum too.

  4. Really great work. I’ve been trying to apply your advice to fix my own issue but I haven’t had any success.

    I have a NPC using Mecanim’s Animator Controller with colliders attached to various bones to represent arms, legs, head, etc. so that they can be locational targets for a Physics.raycast projectile. Except, the raycast can ignore the colliders and go right through them depending on the animation. Sometimes there’s a hit, sometimes there isn’t.

    From my research, it seems this is because although the colliders movement appears to match the animation movement in the game view, they really are not matching up in the physics engine. I’ve tried all of your advice here to fix it- added rigidbodies, isKinematic enabled, set the Animator Controller to Animate Physics, and I set the Fixed Timestep as low as it could go. No success. Setting the colliders to Interpolate does result in 100% accuracy but it severely messes up the animations and can deform the mesh.

    Do you have any advice or experience to share in my specific case?

    1. Hi Lefty, thanks for your comment.

      I’m not sure what could be the issue in your case, other than doing raycast in a wrong place. Are you doing them in Update or FixedUpdate? In general if your stuff moves in physics, you should do the raycasts in fixed update, too. Judging from the fact that using interpolation fixes your issue, it might be this.

      Have you tried visualizing the raycast? Make a “laser ray” that does the raycast every fixed update and then draw the results using Debug.DrawLine, from the laser source to the hit point. Then move the character into the laser ray and make him play some idle anim. Then check the scene view to see what happens. Does it flicker and go through every now and then? Then try doing the laser raycast in regular update, and see if that changes things…

      Also consider using separate “hit skeleton” for raycasts, and normal skinned skeleton for animations. Trying to combine physics behavior (hit detection) with rendering behavior (animation) into one might not get you anywhere.

      In Rochard we had projectiles, but they were “slowly” moving physics triggers. Triggers instead of colliders because colliders would have caused unexpected physics response – we wanted to be in control of the physics response. Maybe just play a simple hit animation, spawn some particles etc… Originally we tried colliders, but that caused really weird physics issues as projectiles moved quickly inside the target (player collider, rigidbody boxes etc) and the collision solver then fixed intersecting physics bodies in unexpected ways.

      Hope this helps some!

      – Sampsa

      1. Thank you so much for your response. It seems this was exactly my problem. The raycasts were being fired in Update. Changing to FixedUpdate has them hitting as they should. I tried for weeks doing everything I could think of but execution order never crossed my mind. Learn something new every day, huh. Thanks again, I’ve learned a lot from this blog, you do some fantastic work.

  5. Quite a nice bit of reading – thanks for that very clear explanation. I have an issue with friction, maybe you can help. Freakin’ friction just wont work. I’m sure the solution is stupid, I just don’t see it.

    Some of my objects have permanent rotation due to a transform.Rotate being applied from my script. But when I press play, although the spinning occurs, they don’t roll on the surface as they should — It’s like there is no friction. Even worse, they move the opposite direction from which they should. All objects affect themselves when they collide with one another, but the rolling effect I expect from their hardcoded spinning motion doesn’t occur. Is it something like “transform.Rotate affects colliders but not rigidbodies” or something like that?

    I tried doing what you proposed in your explanation but it doesn’t solve it.

    Sub-question: Doesn’t “is Kinematic” kill the effect of gravity on rigidbody? Is there a way around that?

    My Unity-Beginner-Self thanks you in advance for your answer.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.