Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

How can you detect, but still physically ignore collisions?

Discussion in 'Scripting' started by markt1964, Nov 11, 2011.

  1. markt1964

    markt1964

    Joined:
    Aug 30, 2011
    Posts:
    83
    I am wanting to detect all collisions in my world, but in some cases I only wish to be notified, and have the objects pass right through eachother, where in other cases, I want to utilize normal collision physics.

    I figured that I can use triggers to set up most of the former case, but there are certain states that my objects can be in where I would not know whether to use a trigger or a normal collision until I can examine the two specific objects that are interacting. Is there any possible way in Unity to set something like this up? I've already considered using layers, but discarded the approach because there are too many different possible state/object combinations to represent with only 32 layers (I would need roughly 1000 layers to unambiguously represent every combination). Going through the list of objects in my scene and explicitly ignoring or enabling collisions between a given object and every other object in the scene whenever the object happens to change state isn't viable, because there are a few thousand objects in my scene.

    Suggestions?

    Thanks in advance
     
  2. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
  3. markt1964

    markt1964

    Joined:
    Aug 30, 2011
    Posts:
    83
    Can I enable a trigger on a collider inside of an OnCollisionEnter function to cause the normal physics collision processing to not happen?
     
  4. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    no, once a collision has happend, you can not... unhappen it. This was the age old argument of why CharacterControllers were great and horrible at the same time.
     
  5. Sycle

    Sycle

    Joined:
    Nov 24, 2009
    Posts:
    446
    Triggers and layer collisions are probably going to be your best bet - a recent situation I had was the player should be able to move cleanly through enemies (but has to know when it happens to take damage - so a trigger) but the enemies have to collide with the world and each other, so they had a non-trigger collider and a trigger collider, and the player layer was set to not collide with non-trigger layer.

    Alternatively you could have everything triggers and fake the physics yourself, or figure out if there is really only a small subset of 'problem cases' where you can't know ahead of time what they're meant to be colliding with, and give them the complex layer setup.

    Or objects can be raycasting ahead of them to 'sense' if they're about to collide with something and switch to a trigger and visa versa. It seems weird that you can only know if an object is meant to be bouncing off another at the time of impact, most likely there's a simpler subset of rules you can implement to get your desired behaviour.
     
    TheCookieNine likes this.
  6. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    just change the layers depending on what you want to collide with, or use raycasts.
     
  7. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    You can kind of "unhappen" collisions manually:

    Code (csharp):
    1. var ignoreTag = "Player";
    2. private var lastPosition : Vector3;
    3. private var lastVelocity : Vector3;
    4. private var lastAngularVelocity : Vector3;
    5.  
    6. function FixedUpdate () {
    7.     lastPosition = transform.position;
    8.     lastVelocity = rigidbody.velocity;
    9.     lastAngularVelocity = rigidbody.angularVelocity;
    10. }
    11.  
    12. function OnCollisionEnter (other : Collision) {
    13.     if (other.gameObject.CompareTag(ignoreTag)) {
    14.         transform.position = lastPosition;
    15.         rigidbody.velocity = lastVelocity;
    16.         rigidbody.angularVelocity = lastAngularVelocity;
    17.         Physics.IgnoreCollision(collider, other.collider);
    18.     }
    19. }
    The only problem with that is a 1-physics-frame hiccup when the collision occurs, where the position will be the same as the last physics frame. You could fix that by using the velocity, but that wouldn't really help if you're using interpolation.

    --Eric
     
    ibrahimpenekli likes this.
  8. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    You can also kind of trick it: A trigger that encapsulates the collider and then enable / disable the collider depending on if you want the collision to take place (platforms where you can jump through from the bottom for example). depending on collider type and unity version the collider will need to be on an own game object to do that.
     
  9. markt1964

    markt1964

    Joined:
    Aug 30, 2011
    Posts:
    83
    There have been some interesting suggestions offered here, and I will try more than one to see how it goes.

    Thanks so much for your help.
     
  10. Serinx

    Serinx

    Joined:
    Mar 31, 2014
    Posts:
    785
    Sorry to necro, just ran into the problem and realised there's a simple solution.

    Add a rigidbody and collider to the parent gameObject.
    Add a child gameObject which has a trigger collider.
    Set the parent and child to different collision layers.

    Hopefully that helps someone in future ;)
     
  11. trueplayer

    trueplayer

    Joined:
    Dec 16, 2013
    Posts:
    7
    Just wanted to say that indeed, it helped me. Thank you!
     
    ZombByeGod, Swift-Games and Serinx like this.
  12. BobbertOC

    BobbertOC

    Joined:
    May 18, 2019
    Posts:
    1
    It did, thanks!
     
  13. alexandre_parent80

    alexandre_parent80

    Joined:
    Mar 30, 2020
    Posts:
    6
    Well I may be very late to that question, but I just got in the same issue today and I made a script allowing to add or remove ignoreCollision with collision collider while keeping trigger colliders untouched, work fine even if you got both a trigger collider and a colision collider on the same gameobject. A bit tricky to do, but it can be done.
     
  14. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,315