detecting the material of a collision object?

Can I detect a physic material in scripting? The following does not work:

function OnCollisionStay( colinfo : Collision )
{
	for (var contact : ContactPoint in colinfo.contacts)
	{
		if (contact.otherCollider.material.name == "Bumper Physic")
		{
			print ("BUMPER!");
		}
	}
}

That does nothing–the if never triggers. It also failed when I tried using == “Bumper Physic Instance” since that string is the output I get from:

print (contact.otherCollider.material.name);

So maybe name is not what I want?

TIA

ignore the following useless topic:
processing contact with more than one object at a time?

Once our player is in contact with the floor, no OTHER contacts get processed. It’s like Unity is ignoring all but the first collider contacted. What am I doing wrong?

Here’s my simple test, attached to the player:

function OnCollisionStay( colinfo : Collision )
{
	for (var contact : ContactPoint in colinfo.contacts)
	{
		print (contact.otherCollider.name);
	}
}

The result: as soon as the level loads, the player contacts the floor, and the floor’s name is printed. Then when the player bumps into other things, nothing is printed for them.

Except… very occasionally–which I think may happen when the player “catches a little air” and thus is not contacting the floor at that precise instant. Then the other collision does get printed to the console.

So how do I get Unity to detect collision with a second object while we’re already in contact with one (the floor)?

(Physically the player does bounce back from all objects–it’s just that my script doesn’t seem to know it.)

TIA!

I tried the script and it worked fine in a simple setup with a couple of colliders and a rigidbody sphere rolling on top of it. And it worked perfectly fine. Are you sure it’s not printing. Maybe you are getting confused by the collapsing of print messages in the console?

Hmmm… yes, it does work, there is no problem, and I don’t know why I thought it didn’t. :shock:

I was raised never to waste a good thread, so I have changed my question above to a REAL one :slight_smile:

collider.material creates a unique instance. This is to prevent modifying the material that is shared between all colliders, which is usually not what you want.

In the process creating a unique instance the name of the material is changed to “Bumper Collider Instance”.

so instead you can check the material name using the sharedMaterial property which will not create a unique instance:

if (otherCollider.sharedMaterial != null  otherCollider.sharedMaterial.name != "Bumper Collider")

Great! Many thanks! I’m always finding new power hidden in Unity.

But now I think I may be hallucinating. The ORIGINAL problem is back: it only detects the first (floor) material it hits, and no others. It’s failing to react to more than one collision at a time, even though physically it’s bouncing back from everything just fine.

Here’s the whole current script:

function OnCollisionStay( colinfo : Collision )
{
	for (var contact : ContactPoint in colinfo.contacts)
	{
		print (contact.otherCollider.sharedMaterial.name);
		if (contact.otherCollider.sharedMaterial.name == "Bumper Physic")
		{
			audio.Play();
		}
	}
}

The audio DOES play if I put “Floor Physic” in the if. It plays constantly.

But it does not play for collisions with things other than the floor (“Bumper Physic”).

(And since it’s a sound, not a Print, I’m sure it’s not just me misreading the console.)

Any leads?

You said it yourself. Use a print to find out exactly what it does.

I did–there’s a Print in there as well. It reports only the “floor” and nothing else, which I then confirmed a second way using the sound.

Depending on your setup, if you use sharedMaterial then it will return null, if you haven’t assigned a physic material to all objects. In that case it will give you a null reference exception.

No nulls, but the problem is found: OnCollisionStay and OnCollisionExit don’t work (since it’s a brief contact that rebounds) but OnCollisionEnter does :slight_smile:

Everything is functional :slight_smile: (But just out of curiosity, why wouldn’t OnCollisionExit work? The player bounces off the bumper, but Exit is not triggered, only Enter. It doesn’t matter, I’m just curious :slight_smile: )

There seems to be an issue where OnCollsionExit is only called when OnCollsionStay also exists. (This will be fixed in 1.6.) The behaviour for OnCollsionStay is that it is only called when it is staying in contact, that is in contact for more than a frame. I think the behaviour will change with 1.6 though because i can see it’s not the most intuitive.

Interesting, thanks :slight_smile:

(It actually does seem intuitive to me that Stay means more than one frame.)

This is a helpful topic. How can you detect what texture material is being collided with? Not the physical material, but the visual one.

C-

You can get at the transform of the object you hit, so then from the transform you can get at the renderer component which contains the material and sharedMaterial of the object. So you would probably want to compare myCollision.transform.renderer.sharedMaterial to something. But be careful because the renderer component will be null if you collide with something without a renderer attached, so you’ll want some if statements in there most likely.

I can provide a code example if that’d be useful, but I think it’s straight forward enough to leave it as an exercise for the reader. (Yummy medicine maybe?)

Cheers,
-Jon

Sorry to bother, having an issue
Could someone please help me convert the ‘for’ loop below into C# syntax.

function OnCollisionEnter( colinfo : Collision ) 
{ 
   for (var contact : ContactPoint in colinfo.contacts) 
   { 
      print (contact.otherCollider.name); 
   } 
}

Your help would be greatly appreciated.