How to check if Trigger is 'empty'?

Hi, all!

I have a trigger that turns the cursor green OnTriggerEnter, and red OnTriggerExit.
However, sometimes that makes it turn red even when things are still inside of it.

I would like it to turn red only when it is completely empty, and turn green the moment anything is inside of it.

it would be along the lines of:

If( triggerIsEmpty){
    GREEN!
}
else{
    RED!
}

Anyone have some real code for my pseudo code? I could only find Enter, Exit, and Stay, and I don’t think that that will work out for me.

Thanks!- YA

6 Answers

6

I know this is a bit old now. But incase anyone finds it in search.

The most simple way to do this is using the OnTriggerStay, and setting a bool to true when the frame starts, and then false if there are any active collisions. I really don’t know why unity doesn’t give you access to a list of all active collisions that a collider has, then you could just check the count on a collider.

public class SlightAdvanceTrigger : MonoBehaviour {

    public bool isEmpty;

    void FixedUpdate()
    {
        isEmpty = true;
    }

    void OnTriggerStay(Collider other)
    {
        isEmpty = false;
    }

}

Thanks for the answer, man! This is old, and I am pretty sure I ended up going with the counting method. Hopefully this will help anyone else that stumbles over here. thanks again!

–

This might be a bit of a overkill.

How about this:

public class SlightAdvanceTrigger : MonoBehaviour {

   private int _count;

   void Start() {
      _count = 0;
     
     //You can setup the trigger here in script, or in the editor, doesn't really matter
   }

   void OnTriggerEnter( Collider other ) {
      ++_count;
   }

   void OnTriggerExit( Collider other ) {
      --_count;
   }

   bool isEmpty() {
      return _count == 0;
   }
}

Please note that I do not know whether if the OnTriggerExit() will be called when a gameobject is destroyed in the trigger. If you have that sort of action, you will need to keep track of the gameobject using a List< T >, and reset the _count accordingly everytime you need to access the _count or isEmpty().

Ha we came up with the same solution. I believe a solution with only OnTriggerStay() could be made too.

–

How to do it using just OnTriggerStay()? Do we need a collection to check whether if a certain gameObject in the trigger is already counted? Or is it some other way that I did not think of?

–

This is how I thought it would go. I was hoping for a magic function but it's not like this is hard or anything. Thanks, guys! - On a side note, I would be interested on how you could use [OnTriggerStay][1] for this. Would it be close to: function OnTriggerStay (other : Collider) { if (other) GREEN! else RED! } [1]: http://docs.unity3d.com/Documentation/ScriptReference/MonoBehaviour.OnTriggerStay.html

–

Well, shoot. It doesn't detect when enemies die -_- How would I go about this, now?

–

Both of these should be able to cope with the scenario where a enemy is killed in the trigger and reset the count properly.

–

You could keep track with a counter of how many objects are in the trigger zone.

private int counter = 0;

void OnTriggerEnter(Collider other) {
    counter++;
}

void OnTriggerExit(Collider other) {
    counter--;
}

and then your pseudocode, which is probably placed in Update(), can be changed to :

if (counter == 0){
    GREEN!
}else{
    RED!
}

Is there any way to check if a collider is empty without using the OnTrigger functions?

I wouldn't think so that seems to be the only way to detect colliders..?

–

An alternative to using Triggers:

public Renderer myRenderer;
public Transform checkOrigin;
public float checkRadius;
public LayerMask checkMask;

void Update()
{
Collider[] checkResults = new Collider[1];
//OverlapSphereNonAlloc does not create garbage
int collidersHit = Physics.OverlapSphereNonAlloc(checkOrigin.position, checkRadius, checkResults, QueryTriggerInteraction.Ignore);
if(collidersHit > 0) {
myRenderer.material.color = Color.green;
}
else
{
myRenderer.material.color = Color.red;
}
}

RaycastHit2D hits;

    private void Update()
    {
            var hits = Physics2D.BoxCastAll(transform.position, Vector2.one, 0, Vector3.back);
            if (hits == null)
                // is empty
    }