OnTriggerEnter & OnTriggerExita pitfall

Hello,

Im got a bit of a problem I was hoping someone could help me out with. Ive got an boxCollider attached to a character that is being used to check objects im passing over (Grid style movement). Works fine except if I pass over two object consecutively the following happens:

I step onto object one and OnTriggerEnter fires foundObjLeft = true;
I start to move onto object two (technically intersecting both object) and OnTriggerEnter fires again setting foundObjLeft = true;
I completely leave object one and OnTriggerExit fires setting foundObjLeft = false :frowning:

Now im on object two with foundObjLeft = false… Any better way of doing this… Im noob to Unty

//
    // Function when we find an object inside this collider
    void OnTriggerEnter(Collider other)
    {
       
        //
        // We found an object left of character
        foundObjLeft = true;
        Debug.Log("OnTriggerEnter" + " " +foundObjLeft);
        //
        // Check object type and
        if (other.gameObject.tag == "tagEnemySub")
        {   
            //
            // Set objectType Detected
            leftObjTypeDetected =1;
        }
    }
   
   
    //
    // Function when we loose an object inside this collider
    void OnTriggerExit(Collider other)
    {   
        //
        // We no longer have an object inside this collider
        foundObjLeft = false;
        Debug.Log("OnTriggerExit" + " " +foundObjLeft);
       
        //
        // Set objectType Detected
        leftObjTypeDetected =0;
    }

Make foundObjLeft a list of GameObjects, then have OnTriggerEnter add the colliding object to the list (other.gameObject) and OnTriggerExit remove the object from the list. Then your check can just be “if list.Count > 0” or “if list.Count == 1” depending on whether you want something to be able to happen while standing on 2 different “tiles” simultaneously.

This also means you can remove the typeDetected, because you can just reference the tags of the objects in the list at any time while they’re in the list (while you’re “over them”), and you can limit certain things to only occur if the list has exactly 1 item.

Im not sure creating a list is possible, the world is never ending and the objects im checking for is randomly generated

The list would be empty at first, and then only ever contain the objects that are being collided with, and only while they’re colliding. Regardless of size or random generation, there would never possibly be move than 4 items in the list at any given time, at least going by your description of the situation (if a character moves diagonally from one square to another, it’s possible to have 4 all at once for a brief moment).

Ahhh I see … ok ill give it a go thanks heaps

mmmm do you have a example of this my C++ to C# is still not great

Something like (pseudocode, untested):

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class SomeClass : MonoBehaviour
{
   private List<GameObject> nearbyObjectList = new List<GameObject>();
  
   private bool somethingNearby
   {
      get{ return nearbyObjectList.Count > 0; }
   }
  
   private bool enemySubNearby
   {
      get
      {
         foreach(gameObject GO in nearbyObjectList)
         {
            if(GO != null && GO.tag == "enemySub")
               return true;
         }
         return false;
      }
   }

   private void OnTriggerEnter(Collider other)
   {
      nearbyObjectList.Add(other.gameObject);
      //OTHER COLLISION ENTER STUFF
   }

   private void OnTriggerExit(Collider other)
   {
      if(nearbyObjectList.Contains(other.gameObject)
         nearbyObjectList.Remove(other.gameObject);
      //OTHER COLLISION EXIT STUFF
   }
}

Even simpler than a list - use a counter. So in OnTriggerEnter, you do objLeftCount++, and in OnTriggerExit you do objLeftCount–

Replace if(foundObjLeft) wherever you use it with if(ObjLeftCount > 0). That should be enough.

Note, though - if you’re ever deactivating any of the objects the collider is on, that won’t fire an OnTriggerExit. In which case the counter would become wrong. So you’ll have to fix that on your own.

Yeah, that was my concern- destroying an enemy for instance. GameObject references have the benefit of becoming null when they’re destroyed, which makes it easy to clean up after. I don’t really like persistent integer counters in the first place, so that might just be my bias, but it feels like there’s a lot more you can do with explicit tracking of nearby objects rather than generic statistical data. The overhead for a list that’ll never be larger than single digits in length is negligible anyways.

This worked , thanks so much