4
\$\begingroup\$

How can I detect if a gameObject has collided with two other specific objects AT THE SAME TIME?

This is what I intend to do but it does not work:

void OnCollisionEnter (Collision col)
{

if(col.gameObject.name == "object1" && "object2")
{
    Destroy(gameObject);
}
}

How can I correct this piece of code?

\$\endgroup\$
4
  • \$\begingroup\$ You've got some solid answers. I'd like to clear something up for you: OnCollisionEnter is called on a per-collision basis. Which is to say, when object1 collides with your object, OnCollisionEnter is called, in which case col is object1. Your logical-and comparison will /never/ be true, since only one collider at a time is processed by the code. \$\endgroup\$ – ketura Oct 4 '15 at 4:36
  • \$\begingroup\$ Also of gamedev.stackexchange.com/questions/109519/…. No need to keep re-asking the same question. \$\endgroup\$ – Trevor Powell Nov 6 '15 at 20:59
  • \$\begingroup\$ @TrevorPowell you're closing these, but he's editing an existing question with what he currently wants answered. It seems like they should be rolled back, not closed (else the existing answers make no sense) \$\endgroup\$ – Problematic Nov 6 '15 at 21:47
  • \$\begingroup\$ Okay, for some reason this user has been editing their previous questions to contain the same text as their new questions; nicely spotted, @Problematic! Rolling back to original text, to preserve the usefulness of the already-existing (and accepted!) answers. \$\endgroup\$ – Trevor Powell Nov 9 '15 at 9:45
4
\$\begingroup\$

You can keep track of collided objects. In simple it looks like:

private bool isCollidedWithObj1 = false;
private bool isCollidedWithObj2 = false;

public void OnCollisionEnter(Collision collision)
{
    if (collision.gameObject.name == "object1")
        isCollidedWithObj1 = true;
    else if (collision.gameObject.name == "object2")
        isCollidedWithObj2 = true;

    if (isCollidedWithObj1 && isCollidedWithObj2)
        Destroy(gameObject);

}

public void OnCollisionExit(Collision collision)
{
    if (collision.gameObject.name == "object1")
        isCollidedWithObj1 = false;
    else if (collision.gameObject.name == "object2")
        isCollidedWithObj2 = false;
}

You can implement more flexible solution:

private List<string> collisions = new List<string>();

public void OnCollisionEnter(Collision collision)
{
    collisions.Add(collision.gameObject.name);

    if (collisions.Contains("object1") && collisions.Contains("object2"))
        Destroy(gameObject);

}

public void OnCollisionExit(Collision collision)
{
    collisions.Remove(collision.gameObject.name);
}

But keep in mind that this code will be much slower, especially for many collisions at the same time. BTW, strings are slow.

\$\endgroup\$
3
  • \$\begingroup\$ Is this code meant for two objects colliding with another one at the same time or for the moment when there are at least two objects attached to another object (then execute an action...)? \$\endgroup\$ – That's me. Oct 6 '15 at 18:17
  • \$\begingroup\$ This code all about detecting "Is object colliding with two other objects in the same time?" \$\endgroup\$ – Exerion Oct 6 '15 at 19:21
  • \$\begingroup\$ If speed is a concern due to using strings, just don't use them. You can have a "private List<GameObject> collisions = new List<GameObject>();" and then later run "collisions.Add(collision.gameObject);" \$\endgroup\$ – MAnd Oct 20 '15 at 3:24
2
\$\begingroup\$

Expanding Exerions answer, you can define public list of GameObjects. This will allow you drag&drop objects in editor which will be collision checked with - no hardcoded values and it removes the need of storing every single collided object name (and optionally also not performing slow string comparisons). Moreover, if you add custom delegate, you can subscribe directly to multiCollisions, like it was built-in event, moving logic onto subscriber. Removing hard-codded strings and logic will make your script much more reusable.

public List<GameObject> CheckedObjects;
private int match_count = 0;

public delegate void FireAction(GameObject obj);
public event FireAction OnMultiCollisionEnter;
public event FireAction OnMultiCollisionExit;

void OnCollisionEnter(Collision other)
{
    if (collisions.Contains(other.gameObject))
    {
       match_count++;
       if(match_count == CheckedObjects.Count)
          OnMultiCollisionEnter(this);
    }
}

public void OnCollisionExit(Collision collision)
{
    if (collisions.Contains(other.gameObject))
    {
       if(match_count == CheckedObjects.Count)
         OnMultiCollisionExit(this);
       match_count--;
    }
}

note: did not checked if object can enter twice without exiting, if that is possible, store set of currently colliding objects instead of incrementing logical value

\$\endgroup\$
2
  • \$\begingroup\$ Is this code meant for two objects colliding with another one at the same time or for the moment when there are at least two objects attached to another object (then execute an action...)? \$\endgroup\$ – That's me. Oct 6 '15 at 18:17
  • \$\begingroup\$ @Anonymous it fires when all specified objects in CheckedObjects list are colliding with the object this script is attached to (CheckedObjects does not have to be attached(=children of) to the object - it is list of references). For example if you added "object1" and "object2" objects to the list, it would fire when they are both colliding. You can also modify this code very easily to fire, for example, when at least half/2/3/n of the objects collide. \$\endgroup\$ – wondra Oct 6 '15 at 18:38
-1
\$\begingroup\$
if (col.gameObject.tag == "object1" && col.gameObject.tag == "object2")

You forgot the 2nd col.gameObject.id

Sorry... I changed the name to tag (you must tag the object first)

\$\endgroup\$
6
  • \$\begingroup\$ error CS0019: Operator ==' cannot be applied to operands of type UnityEngine.GameObject' and `string' \$\endgroup\$ – That's me. Oct 3 '15 at 14:43
  • \$\begingroup\$ What was the final solution? I'm curious \$\endgroup\$ – DUUUDE123 Oct 6 '15 at 23:12
  • \$\begingroup\$ The final solution was yours! :) \$\endgroup\$ – That's me. Oct 7 '15 at 10:54
  • \$\begingroup\$ The simplest one! \$\endgroup\$ – That's me. Oct 7 '15 at 10:57
  • \$\begingroup\$ @Anonymous if this answer solved your probably, you should consider selecting it as the correct answer. \$\endgroup\$ – MAnd Oct 20 '15 at 3:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.