Adding rigidbody engages children colliders?

Hello,
after looking at the forums and answers for this problem i saw that it didn’t really match mine, here’s what i do: i have some pieces (lego-like) which have their custom colliders (screenshot below) and they have the “connection points” which are using box colliders to trace mouse clicking, entering and leaving - visible as the smaller cubes below:

3310-01.png

However, when i add a rigidbody (via script) to the parent piece, all the children seem to give their colliders to the rigidbody, thus i lose the mouse functionality over them, and they now act as part of the parent rigidbody, even colliding with each other like this:

3311-02.png

is there a way to get my connector colliders back and not let them be part of the parent rigidbody? i’ve tried using Destroy(rigidbody) but nothing changed.
Any ideas?
Thank you!

A rigidbody always catch all events from every colliders and child colliders. This is the way to create a compound collider.

So either don’t use a rigidbody on the parent object, or don’t parent every child under a common parent.

Another workaround is to add a rigidbody to every child so that collision events will not be propagated to the parent rigidbody. The question is: why do you need a parent rigidbody?

YOU FOUND A BUG.

Make a new project with a scene. have two objects, a large and a small cube. give them DIFFERENT names. Make the small cube a child of the big cube.

Attach this script it to BOTH OBJECTS:

#pragma strict

// this script shows the Unity BUG ....

function Update() // WORKS PROPERLY all four combos
	{
	var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
	var hit : RaycastHit;
	if ( Input.GetMouseButtonDown(0) )
		if (collider.Raycast (ray, hit, 100.0))
			{
			Debug.DrawLine (ray.origin, hit.point, Color.green, 1 );
			Debug.Log("YOU CLICKED ON ......" + transform.name);
			}
	}
function OnMouseEnter () // UNITY BUG - DOES NOT WORK for combo 3
	{
	Debug.Log("TESTE OMENTER");
	renderer.material.color = Color.red;
	}
function OnMouseExit () // UNITY BUG - DOES NOT WORK for combo 3
	{
	Debug.Log("TESTE OMEXIT");
	renderer.material.color = Color.white;
	}

Try these four combinations of

parent … child
no rigidbody, no rigidbory
no rigidbody, yes rigidbory
yes rigidbody, no rigidbory
yes rigidbody, yes rigidbory

#EVERYTHING WORKS PERFECTLY WITH RAYCASTING

double-checked… note the image below

#WITH ONMOUSE, COMBO #3 DOES NOT WORK.

So that’s it. Someone telephone Unity.

Your solution: do not use OnMouseEnter / OnMouseExit. Achieve same result with ordinary casting.

SOLUTION SCRIPT:

// this works perfectly but (correctly) has the 'shoot through' issue
// see 'ultimate solution' below if you prefer not shoot-through
function FixedUpdate()
	{
	var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
	var hit : RaycastHit;
	if (collider.Raycast (ray, hit, 100.0))
		{
		Debug.DrawLine (ray.origin, hit.point, Color.green, 1 );
		renderer.material.color = Color.red;
		}
	else
		{
		renderer.material.color = Color.white;
		}
	}

Simply try that. You’ll see it works perfectly in all four combos. Phew!

There is a problem, a raycast shoots through everything, so, you will get BOTH when one blocks the other. See image. (Note that the whacky OnMouse functions are “strange” or that very reason, they only find the one near the camera. It’s useful for a quick development script say, but strange, and since they are broken we need an alternative!)

Now depending on your project, that could be no good. Again the solution script presented immediately above will get any object, not just the one closest to the screen. (Of course another issue is you can adjust the length if desired with the parameter that says “100.0” in the example…often you want to ignore things that are “too far away” in the scene, in this type of thing.)

#ULTIMATE SOLUTION …

// this solution FULLY TESTED with all four combos, all good
// attach to an empty object "operations" in the scene

private var theCam:Camera;
private var yellowRay: Ray;
private var theHit : RaycastHit;
function Awake()
	{
	theCam = GameObject.Find("cam").camera;
	}
function FixedUpdate()
// no need to do this in Update(), FU is usually
// easily fast enough for smooth fingering
	{
	if ( Input.touches.Length != 1 ) return;
	yellowRay = theCam.ScreenPointToRay( Input.touches[0].position );
	if ( Physics.Raycast (yellowRay, theHit, 100.0 ) )
		{
		Debug.Log("theHit.collider.name " +theHit.collider.name);
		// for example ...  theHit.collider.transform is the object
		// you'd likely just look them up from here, eg
		// if ( theHit.collider.transform == mySpaceship ) whatever..
		// if ( theHit.collider.transform.name == "13" ) whatever..
		// or you could do this ...
		// theHit.collider.transform.GetComponent(BlahScript) ...
		}
	}

Make a new empty game object. (I usually call these something like “operations” or “headquarters” … it takes care of “things on the whole scene”.) Put that script in the new empty object. Do not put ANY scripts on the small and large cube.

You’ll see it works absolutely perfectly AND you avoid the “shoot through” issue, i.e. only the closest object touched is chosen. (Again you may want to shoot “all the way through” and have all such objects react; in that case use the other method above.)

So, that’s it.

To see the red-white effect in testing, just do this:

var aa:Renderer;
var bb:Renderer;
private var theCam:Camera;
private var yellowRay: Ray;
private var theHit : RaycastHit;
function Awake()
	{
	theCam = GameObject.Find("cam").camera;
	}
function FixedUpdate()
	{
	aa.material.color = Color.white;
	bb.material.color = Color.white;
	
	if ( Input.touches.Length != 1 ) return;
	
	yellowRay = theCam.ScreenPointToRay( Input.touches[0].position );
	
	if ( Physics.Raycast (yellowRay, theHit, 100.0 ) )
		{
		Debug.Log("theHit.collider.name " +theHit.collider.name);
		theHit.collider.transform.renderer.material.color = Color.red;
		}
	}

Hope it helps! What do you win from Unity when you find a bug?

Sorry I wasted so much of your time, at first I ignored that you mentioned OnMouseEnter/Exit. I foolishly assumed all the casting versions in Unity would be equally bug-free.

But you know what they say … ASSUME makes an ASS out of U and ME ! :slight_smile: