3
\$\begingroup\$

I have a GameObject. It has 3 BoxCollider2Ds:

  1. Body Collider - Not a trigger - Determines if body is hit
  2. Weapon Collider - Trigger - Determines if weapon is hit
  3. Vision Collider - Trigger - Determines what the GameObject sees

I can tell the Body Collider apart from the other colliders, because it has a different method (OnCollisionEnter2D). However, I cannot tell the Weapon Collider and Vision Collider apart. They both access the same method (OnTriggerEnter2D), and pass in the collider they are hitting. I cannot determine which one is hit.

I could put each trigger on a separate child GameObject, and send a message to the parent, but this is very slow and feels messy to me. What is the best way I can determine which trigger I am hitting?


From the Unity Docs for reference:

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour {
    public bool characterInQuicksand;
    void OnTriggerEnter2D(Collider2D other) {
        characterInQuicksand = true;
    }
}
\$\endgroup\$
  • \$\begingroup\$ I think putting the triggers on separate child-objects is the best solution. You can avoid the overhead of SendMessage by using transform.parent.GetComponent<ExampleClass>() in the scripts of the child-colliders. \$\endgroup\$ – Philipp Jun 21 '16 at 23:20
4
\$\begingroup\$

You might have some success checking the Collider2D.IsTouching method in your OnTriggerEnter.

void OnTriggerEnter2D(Collider2D col)
{
    if (weaponCollider.IsTouching(col)) { /* Weapon */ }
    if (sightCollider.IsTouching(col)) { /* Sight */ }
}

IsTouching is polled against the last physics update so it should be pretty light weight.

However, if your colliders overlap, it might be best to process the triggers during OnLateUpdate or keep tabs on the touching colliders separately.

HashSet<int> collidesWithWeapon;
void OnTriggerEnter2D(Collider2D col)
{
    if (weaponCollider.IsTouching(col)
       && !collidesWithWeapon.Contains(col.GetInstanceID()))
    {
       collidesWithWeapon.Add(col.GetInstanceID());
       // Weapon stuff
    }
}

void OnTriggerExit2D(Collider2D col)
{
    if (!weaponCollider.IsTouching(col)) collidesWithWeapon.Remove(col.GetInstanceID());
}

I'm pretty sure there are other curve balls along the way, but hope this helps forward. Adding the colliders to other GameObjects might help too, but I think trigger events cascade top to bottom or something similar. Can't remember what it was exactly, though... Whatever it was, I've made it a practice to check the IsTouching() if the hierarchy contains more than one collider.

| improve this answer | |
\$\endgroup\$
  • 2
    \$\begingroup\$ This is an awful question, because 9 out of 10 answers are to some other question. This answer is the 1 out of 10. Thanks! I am going to try it out later today. This may be the solution I've been searching for. \$\endgroup\$ – Evorlor Jun 22 '16 at 15:06
  • \$\begingroup\$ I know what you mean. Good luck! \$\endgroup\$ – volvis Jun 23 '16 at 5:49
0
\$\begingroup\$

I fail to see what your problem is with making child objects. Just make two objects as children of your "body" object, make a script saying:

public GameObject body;

OnTriggerEnter2D(Collider2D other)
{
    body.characterInQuicksand = true;
}

Attach it to whichever of the children is supposed to have it, assign the variable body in the inspector and you're done.

| improve this answer | |
\$\endgroup\$
-1
\$\begingroup\$

I think you can use GetComponent<Collider2D>().name to determine the current collider being used in OnTriggerEnter. I did a quick test with this Debug.Log(other.name + "hit" + GetComponent<Collider>().name); and it seemed to work ok as long as the triggers did not overlap.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I have multiple Colliders. \$\endgroup\$ – Evorlor Jun 22 '16 at 14:38
-1
\$\begingroup\$

Also, you can use CompareTag.

Firstly, you must to add tag your game objects.

Then: public class PlayerClass : MonoBehaviour { void OnTriggerEnter2D(Collider2D other) { if (other.CompareTag("OtherGameObjectTagHere")) Destroy(other.gameObject); } } }

Please check this out https://docs.unity3d.com/ScriptReference/Component.CompareTag.html

| improve this answer | |
\$\endgroup\$

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.