Unity3D Physics 2D issues in Unity 5.0.1

Recently I upgraded a project from unity 5.0.0 to Unity 5.0.1 and discovered some quite erratic behaviour in the game. Note that the game has been in development for many months without issues across versions of unity from 4.3 onwards.

Update:

As a great example of how Unity are rapidly fixing bugs they replied within 2 days of me filling the bug confirming that they had reproduced it and had a fix. This was publicly available within 2 weeks as patch 5.0.1p3. Thankyou!

It shows that it’s worth while everyone taking the time to create a reproducible report of issues they discover.

Summary:

In Unity 5.0.0 patch 3 onwards including 5.0.1

(Tested up to latest release Unity 5.0.1 patch 1):

  • If you set the RigidBody2D.CenterOfMass the inertia value will be calculated incorrectly which can cause erratic behaviour.
  • Any prefabs (and possibly scenes) containing joints which had the collideConnected flag set will no longer have it set (and it’s now renamed to enableCollision) which will mean some objects no longer collide.

I have reported these issues as bug 691289.

Issue 1: Erratic behaviour after a collision.

When our character crashes their bike’s front suspension would go crazy, often sending the bike flying but eventually settling down with overly compressed with the wheel going through the bike’s body.

Many things are changed on a crash, but one by one they were ruled out until one was remaining. We have a child gameobject on the bike body which contains a box collider which is used for colliding with coin triggers and picking them up. It’s on it’s own layer and only interacts with the coins. When the user crashes this is switched off (as the player is ejected and we only want the player to collect coins after that)

So I created a testbed to investigate further and rolled back the versions of unity one patch at a time until I discovered that the behaviour was introduced in 5.0.0 patch 3

SetCoMWrongBike 1 shows something close to what we have in game. Note that the red dot is the centre of mass (CoM) which we set via script.

Bike 2 shows how the bike settles after a crash. The bike is identical it just has the child BoxCollider2D disabled. I spent some time trying to identify a change in the wheel collider’s suspension, but none existed.

Bikes 3 & 4 mirror 1 & 2 with the exception being that we no longer set the CoM.

Bike 5 is just the bike body with he CoM set, notice that the inertia value is negative and the bike even intersects the floor as it erratically moves about.

Bike 6 is the same as Bike 5 but we no longer set the CoM

Running the same scene in Unity 5.0.0 patch 2 and previous versions results in the behaviour we would expect:

SetCoMWorkingReading the release notes and I suspect that the changes to implement the following have caused this issue:

Physics 2D: Center-of-mass and Inertia can now be set on a Rigidbody2D component even if it has no Collider2D components attached.

Once I had identified that the inertia values were wrong I was able to implement the following temporary fix which resets the inertia after editing the CoM:

float defaultInertia = body.inertia;
body.centerOfMass = transform.localPosition;
body.inertia = defaultInertia;

Should a child object effect the centre of mass?

Notice that between bike 3 and 4 the centre of mass moves down, this is not what I thought would happen. I believed that the only items to effect the rigid body would be those on the same gameobject as the rigid body it’s self.

This does pose the question of is this the intended behaviour and if so what is the best way to add additional colliders that move with the physics but do not alter the behaviour?

Please tweet any ideas to @hersee

You can download the unity project used to test this here: Physics2DIssue  Use the scene window rather than the game window to see the collider outlines.

Issue 2: Our biker’s body started to travel through the bike.

This took longer to identify than it should due to a red herring. The following release note put us on the right track:

Physics 2D: Joint2D property ‘collideConnected’ renamed to ‘enableCollision’ to match 3D physics.

However I started at the wrong place, the hands which are connected to the handlebars. What was interesting was that disabling this joint caused the body to start to collide again. It wasn’t until a day later that I discovered the game code used the hinge enabled flag to control wether another joint should be active.

This other joint was indeed the issue as it connected the body to the bike, giving it a maximum distance it could travel. Anyway to cut a long story short if you have prefabs with joints that had the collideConnected flag set to true originally they will now have the new enableCollision flag but it will be set to false. Hence the connected object will no longer collide with what it is connected to.

At least that was a simple fix once discovered! Although I’m not sure why Unity’s FormerlySerializedAs attribute did not take care of this. Perhaps it’s not being used or there is a use case with prefabs where it does not work. I’ve done enough tracking down Unity’s issues today to bother checking this, also I don’t know if the same thing occurs with joints in scenes or if it’s just prefabs.

4 thoughts on “Unity3D Physics 2D issues in Unity 5.0.1”

  1. Hi, I’m the guy @ Unity who’s looking at this case which I’ve now fixed thanks to your bug report. To answer your question about children affecting the COM; yes they do/should. Adding a child collider attaches to the parent (if any) Rigidbody2D. This is done to support how Unity favors using the transform-hierarchy to position objects and then be able to reference their position later in script easily. As you may know, Box2D likes to calculate mass/inertia based upon collider density but Unity wants to expose mass directly as a property of the Rigidbody2D. This means we have to interfere with how Box2D wants to work and override this. Adding a Collider causes a recalculation of the COM/inertia but if you’ve explicitly specified a COM or rotational inertia then we just set it to that (or at least that is what is supposed to happen). 😉

    I noted your issue of the the rename to ‘enableCollision’ not upgrading data saved in prefabs which surprises me as that should happen as well as all the script references being updated as well. Internally, the native C++ side of things knows that old and new properties names and uses them as an equivalence so it should be seamless. I’ll investigate that later today.

    I hope this helps clarify stuff for you; sorry for the issue you’ve had.

    @melvmay

    1. Thanks for the really quick resolution on this issue and replying! It’s fantastic that Unity are now able to fix these issues and get patches out within weeks, shows us all that it’s worth while taking the time to create good bug reports.

      Apologies for not updating this post earlier, or moderating this comment earlier, I’m so used to comments being spam!

      1. No problem at all. Staying on top of bugs for 2D physics is really important for me, especially with regressions. There were a lot of moving parts in the 5.0 release and the patch releases allowed us to provide a quick turn-around on bugs, especially serious ones, typically less than a week.

        Hopefully things have settled down now!

Leave a Reply