Unity 5 - Can't change Rigidbody rotation constraints

In my current project most characters’ movement is controlled by the physics engine. User/AI input adds forces. In Unity 4, characters had rotation constraints (X and Z axis) to prevent them from “falling over”. Those constraints were removed once the character was “killed”.

When upgrading to Unity 5, I noticed that “unfreezing” rotation no longer worked. I assume this is because rotation constraints are now realized via the tensors, which, apparently, never get updated.

My current workaround is to manually reset the rotation every frame, which has an unacceptable perfomance impact (directly setting position or rotation of a physics-controlled object is never a good idea and causes a lot of recalculation) and is also not very elegant.

Are there any alternative solutions? Perhaps a way of triggering a recalculation after changing the constraints? Or a more efficient way of preventing unwanted rotation?

only if youre doing it wrong

Care to elaborate? What would be a good way to do this?

doing it wrong means doing it via transform functions, rather than the physics based methods (moveposition/moverotation/forces)

Well, yeah, of course MoveRotation is faster than just setting rotation (in most cases). It’s still a lot of unnecessary overhead if you have to do it on a lot of complex objects. You still move the object and then reset it. Which is what, according to the docs, the Unity devs intended to avoid by using the tensors for rotation constraints.
Even worse, since I have to do it manually from code, what happens now every frame is that forces cause the object to rotate, the physics engine having to do all the necessary calculations, then the script tells it to move the object back, doing all the calculations again, just in the opposite direction.
That’s neither very elegant nor very efficient.

What I’m looking for is a way to avoid this back-and-forth altogether, for example by forcing the engine to recalculate the tensors when required (the change happens once in the object’s lifetime) so I could use the rigidbody constraints.

Freezing the rotation can be done by:

GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezeRotationZ;

If that’s what you’re after.

1 Like

That’s what I did originally, and it worked well in Unity 4, but with Unity 5 changing the rotation constraints after the object has been initialized does not appear to have any effect.

Have you tested this? Does it work with your version of Unity? If so, which version?

I have this:

if (Input.GetKeyDown(KeyCode.Alpha1)) // Rotation Freeze
        {
            GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezeRotationZ;
        }

Which works perfectly for me (Unity 5.1.1f Personal).

The object can still rotate if you specifically tell it to but it stops physics from rotating it.

Interesting. Maybe they fixed it in the meantime? Thanks, I’ll give it a try.

Okay, I’ve thoroughly tested this again. The findings:

  1. Setting all three rotation constraints actually worked. The object did not rotate.
  2. However, setting just two of the FreezeRotation flags, no matter in what combination, had no observable effect. The object rotated along all axes.
  3. Removing constraints (unfreezing) by setting GetComponent().constraints = RigidbodyConstraints.None had no observable effect.

Just did a quick test and all 3 are working as expected for me.

The only thing I can think of is that maybe your object’s rotation is being set somewhere else :frowning:

If I could give you a high five right now I would. Thank you!