Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

detecting the material of a collision object?

Discussion in 'Scripting' started by Morgan, Oct 6, 2006.

  1. Morgan

    Morgan

    Joined:
    May 21, 2006
    Posts:
    1,223
    Can I detect a physic material in scripting? The following does not work:

    Code (csharp):
    1.  
    2. function OnCollisionStay( colinfo : Collision )
    3. {
    4.     for (var contact : ContactPoint in colinfo.contacts)
    5.     {
    6.         if (contact.otherCollider.material.name == "Bumper Physic")
    7.         {
    8.             print ("BUMPER!");
    9.         }
    10.     }
    11. }
    12.  
    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:

    Code (csharp):
    1. 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:

    Code (csharp):
    1.  
    2. function OnCollisionStay( colinfo : Collision )
    3. {
    4.     for (var contact : ContactPoint in colinfo.contacts)
    5.     {
    6.         print (contact.otherCollider.name);
    7.     }
    8. }
    9.  
    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!
     
  2. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    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?
     
  3. Morgan

    Morgan

    Joined:
    May 21, 2006
    Posts:
    1,223
    Hmmm... yes, it does work, there is no problem, and I don't know why I thought it didn't. :eek:

    I was raised never to waste a good thread, so I have changed my question above to a REAL one :)
     
  4. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    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:
    Code (csharp):
    1.  
    2. if (otherCollider.sharedMaterial != null  otherCollider.sharedMaterial.name != "Bumper Collider")
    3.  
     
  5. Morgan

    Morgan

    Joined:
    May 21, 2006
    Posts:
    1,223
    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:

    Code (csharp):
    1.  
    2. function OnCollisionStay( colinfo : Collision )
    3. {
    4.     for (var contact : ContactPoint in colinfo.contacts)
    5.     {
    6.         print (contact.otherCollider.sharedMaterial.name);
    7.         if (contact.otherCollider.sharedMaterial.name == "Bumper Physic")
    8.         {
    9.             audio.Play();
    10.         }
    11.     }
    12. }
    13.  
    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?
     
  6. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    You said it yourself. Use a print to find out exactly what it does.
     
  7. Morgan

    Morgan

    Joined:
    May 21, 2006
    Posts:
    1,223
    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.
     
  8. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    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.
     
  9. Morgan

    Morgan

    Joined:
    May 21, 2006
    Posts:
    1,223
    No nulls, but the problem is found: OnCollisionStay and OnCollisionExit don't work (since it's a brief contact that rebounds) but OnCollisionEnter does :)

    Everything is functional :) (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 :) )
     
  10. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    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.
     
  11. Morgan

    Morgan

    Joined:
    May 21, 2006
    Posts:
    1,223
    Interesting, thanks :)

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

    cgoran

    Joined:
    Jun 11, 2005
    Posts:
    176
    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-
     
  13. Jonathan Czeck

    Jonathan Czeck

    Joined:
    Mar 17, 2005
    Posts:
    1,713
    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
     
  14. bernieoneill

    bernieoneill

    Joined:
    Aug 11, 2009
    Posts:
    3
    Sorry to bother, having an issue
    Could someone please help me convert the 'for' loop below into C# syntax.

    Code (csharp):
    1.  
    2. function OnCollisionEnter( colinfo : Collision )
    3. {
    4.    for (var contact : ContactPoint in colinfo.contacts)
    5.    {
    6.       print (contact.otherCollider.name);
    7.    }
    8. }
    9.  
    Your help would be greatly appreciated.