Rigid Body collision problem

Hi, I’ve submitted this question before, and on request of a user I added a picture. I also defined the problem more sharply after some tests with the help of some tips this user gave me.

I have a player controlled object, object A. It consists of 2 parts, A1 and A2, which should be locked to each others position. Object B is identical, and can be player controlled or AI controlled.

The goal is as follows:

All parts should be able to collide with each other, and react to physics, as long as the positional lock between two parts(A1 & A2 and B1 & B2, respectively) is kept intact.

All parts should have different colliders. If A1 collides, A2 should NOT receive a collision message.

For some reason, I cant get this to work. I’ve tried joints, kinematics and all sorts of parent child setups, but I can’t seem to get the aimed results. Kinematic parts won’t collide with each other and separate colliders require separate rigid bodies, which are hard to keep together (as they react to physics individually). Kinematic rigidbody triggers do work, at least code-wise but do not adhere to physics. :frowning:

Alternatively, a workaround could be if I could make a single collider and detect which side was hit. Is such a thing possible?

Thanks in advance!


It couldn’t be easier champ:

Here’s the full working code. put this on the WRAPPER object, the OVERALL object:

function OnCollisionEnter(cc:Collision)
    Debug.Log("I got hit ... ny name is ... " + gameObject.name);
    Debug.Log("but even better, here's the specific collider on this side ... " +
           cc.contacts[0].thisCollider.name );

Look at the image. NOtice the game object called “GameObject” is the WRAPPER object, that’s the OVERALL object.

This is completely normal. Almost every single object ever done in Unity would look like this. You have the rigidbody on the WRAPPER object and the colliders on objects BELOW THAT.


Note - in the example say you particularly want the sphere or the cube to “get” the message that they have been hit. ie for some reason you would particularly rather the code for “cube hit” was actually on the cube. What you do is send that message down to the cube. So you would have a script on the cube called cubeControl. You would modify the sample code above lije this …

  if cc.contacts[0].thisCollider.name == the cube, then

  if cc.contacts[0].thisCollider.name == the sohere, then

you understand? Again - this is utterly SOP. Virtually every object ever done in Unity would have this! (Other than the most trivial test projects.)

Don’t forget here is the exact forumla:

remember only ONE object has the RIGIDBODY – the HIGHEST LEVEL object.

put EACH OLLIDER on SEPARATE holder objects UNDER that object.

put my EXAMPLE script on the HIGHEST object (the one WITH the RIGIDBODY)

Finally don’t forget as I explained at great length:

When your objects fly apart the way you make video games is they change to different objects

This is completely normal, you have to do the work and you can’t “magically” avoid that.

For exampleL in my image say the sphere broke-away. Note that just to begin with the sphere would now need a rigidbody!! It is now a HUGELY DIFFERENT SORT of object!!

It may now be part of a pool in your game, it may be a ragdoll, it may have to float, bounce (who knows), it may be explosive, it may have unusual sound effects … who knows?

It’s a totally different object, this is not magic – you must program that

As I explained at length, very often you actually secretly swap to another object even though the player will think it’s the “same” objects as before.

i hope it helps!

Again the total answer to what you are asking is exactly the same code at the top here.

I can offer a suggestion regarding this:

Alternatively, a workaround could be if I could make a single collider and detect which side was hit. Is such a thing possible?

I think it’s definitely possible if you use the Collision.contacts property inside your collision events. Easiest thing would be to take the first contact point and use the normal to decide on which side the collision happened.

To elaborate, assuming that you have a root object A that is the parent of both A1 and A, with the A1 to the right and A2 to the left of the center, so that the local coordinates are like so:

          +--> x
+--------+ +----+
|   A1   | | A2 |
+--------| +----+

Then take the normal of the collision contact point and translate it into A’s local coordinate space using Transform.InverseTransformPoint. This new normal can be used to find on which side the collision happened using the dot product:

if (Vector3.Dot(n, Vector3.right) > 0))
  Debug.Log("Collision happened on the right side of A, i.e. A2");
  Debug.Log("Collision happened on the left side of A, i.e. A1");

Of course this isn’t 100% percent accurate, but it might be a good enough. There’s probably a more elegant solution to this issue, but I must confess I’m not fully grokking your requirements.