4.5 - Collision Events in Parents

So I’ve upgraded to 4.5, and the new collision event behavior is giving me a problem.

In 4.3, collision events went to the script attached to that GameObject. In 4.5, they also go to the script of the associated Rigidbody2D parent GameObject. Very convenient - sometimes.

But I need to distinguish these events, and there’s nothing in the parameters which specifies which of MY colliders had the collision. My enemies are now avoiding my player like he’s a wall. I can only try to reverse engineer the answer by figuring out what and/or where it got collided with, which is less than ideal.

I went to some effort to arrange my Layers so that any given collider is strictly picking up the collisions it’s interested in. This is throwing that effort away and forcing me to re-enact that behavior in the scripts, without even giving me the proper tool to do so.

EDIT: Another subtle change that threw me for a loop: in 4.3, if you disabled a collider mid-collision, all the collision events would fire anyway, at least as far as I ever saw. In 4.5, any “subsequent” events (at the same time) will not fire, leading to inconsistent results.

Pyrian, it appears that I share your pain.

My player object has a spawn controller as a child object with bigger-than-the-screen-sized triggers that spawn and de-spawn enemy objects around it.

Just spent all afternoon puzzling why my player object was getting killed by attacks that were clearly not touching it - turns out the spawn/despawn triggers were colliding with the attacks and passing the OnTriggerEnter2D all the way up to the player object…

Before I embark on a mass of refactoring I’d love to know if this is a bug in 4.5 or an intentional change in Physics2D that will affect functionality from now on.

(And if this is an intentional change in behaviour, as you say, what is the method by which the object that OnTriggerEnter2D is called on can work out which of its colliders is involved in the collision?)

Rather concerned, since I have objects that have different parts that have different vulnerabilities and up until now was relying on the fact that each child object had a Collider2D and a script on it that described that vulnerability…(!)

It would appear that it is indeed an intentional change (from http://unity3d.com/unity/whats-new/unity-4.5) :

Physics: Collision and trigger callbacks now occur on both the GameObject containing the 2D collider as well as the GameObject containing the 2D rigid-body.

Looks like I’m about to embark on a One Way Trip to Workaround City. Sheesh…

I have this issue as well. I have a player wielding a sword as a child object. Now when the sword gets hit, my player gets damaged. Less than ideal.

Does anyone have a fix or workaround for this? Is there a way to tell which gameobject or collider received the collision?

One workaround is to do all your events on child objects, and not catch the events at the rigidbody GameObject at all. PitA, I know; at first glance I’m like, “hooray, I can do all my event processing in a single script instead of having little pass-through scripts at each child” but instead we’re creating MORE pass-through scripts.

That was my solution too - move all the collision off the player parent object that contains the Rigidbody2D and do all the OnTriggerEnter2D processing a long way away from it in child objects and pass up the hits to the control object.

To solve the problem I had with my bigger-than-the-screen spawn/despawn triggers was to move those into a separate physics layer, and then add an extra child object and collider to anything that spawns so they would only interact with those triggers.

The net effect being that I’ve created more child objects on everything and added more colliders in the scene just to work around this erm… ‘feature’.

So, kathode…

Yep - since OnTriggerEnter2D is now less useful on your main player object (with the RigidBody2D on it) you might need to consider moving everything off the main player object into child objects.

First off - set up Physics Layers so that your Sword is in a different physics layer from the rest of your player body, and then perhaps organise like this:

Parent Player Object (has RigidBody2D on it)
|__ Child Player Body Object (has player body Collider on it and your PlayerControl script with the OnTriggerEnter2D in it)
|__ Child Sword Object (has sword Collider on it)

In that way you’ll know that your PlayerControl script’s OnTriggerEnter2D is only going to be affected by colliders that touch it and since the Sword is in a different Physics layer it should never interact with the body colliders.

If you need to add more systems, add them in as Child Objects to the Parent Player Object with their own scripts and you’ll at least know which colliders are being triggered.

The pain here, of course is that your control routines have to reference the parent’s transform to move it around.

The alternative set-up would be to keep your control routines on your Parent Player Object and then create a ‘Vulnerability’ script on your Child Player Body Object that looks for OnTriggerEnter2D events and then if a hit is taken, passes that info up to your control routines

I can see the benefits of the change, but without being able to discern which collider the OnTriggerEnter2D event is being triggered on we’re going to have to be more distributed in the way we process this sort of thing which means a more complex system, more scripts and more objects in the scene that have to be processed.

Good luck!

SimesPh - thanks so much for the detailed response. I think I could change my character pretty easily as you describe.
But after thinking through it, I’m falling back to 4.3.4. I’m having other more subtle problems with physics with my character becoming more slippery all of the sudden, and even going completely wacky and bouncing around like a pinball in some situations. Given how heavily I rely on the physics engine, I’m heading back into familiar territory until this release stabilizes a bit.
Thanks again though!

I ended up adding tags to things so that I didn’t have to move anything around. But I know eventually I’ll run into a case where I’d need two tags on something, so I like the layer approach more.