Not calling OnTriggerStay()

I am trying to find a way to call OnTriggerStay to represent leaving a Trigger Collider, which has been destroyed. An OnTriggerExit is not going to help me, as the collider has been destroyed and is never exited properly.

According to the API for OnTriggerStay, “This message is sent to the trigger and the collider that touches the trigger”. I guess this means that I cannot call an opposite of stay within OnTriggerStay, as there is no collider touching a trigger.

At first I thought that the following may have worked:

void OnTriggerStay (Collider other)
    {
        if (!other is BoxCollider)
        {
            print("Not in the Trigger Collider");
        }
    }

I was thinking that looking for !other is BoxCollider within Update could be a way to constantly look for this collider. I do think however, that it would be inefficient and bad practice.

Could anyone please advise on how I could go about looking for a collider of a different object, that no longer exists (that has not been exited) in order to call a function?

Thank you.

I think the easiest way would be to attack this from the opposite angle. Keep a track of what the deletable object is colliding with frame by frame and have an OnDestroy function which then informs those things “hey I’m about to disappear do what you need to do”

1 Like

This thing:

!other is BoxCollider

Is parsed like this:

(!other) is BoxCollider

As the ‘!’ operator has precedence over the ‘is’ operator.

The !other thing returns a bool, since Unity (in their infinite visdom) decided to have an implicit conversion from UnityEngine.Object to bool, in order for you to be able to write:

if(someComponent) {...} 
//instead of:
if(someComponent != null) {...}

So, your code will compile, but not work. If you try to do the same thing with a non-Unity object (like a string), you’d get a compilation error:

string s = "lol";
if(!s is BoxCollider) {...} //Does not compile; "Operator '!' cannot be applied to operand of type 'string'

To get your intended behaviour, use parantheses:

!(other is BoxCollider)
1 Like

Oh, and a solution to your problem would be to store the BoxCollider on Enter, and check if it has become null in Update. If it has become null, call the same method that OnTriggerExit would have called.

1 Like

Thanks @LeftyRighty .

It sounds like you’re saying that something like:

if (other object isDestroyed)
{
do stuff;
}

To refer to the other object (object B), it would need to access its properties and know it appertains to it. If OnTriggerEnter, object B is linked to object A, which then will track whether it exists.

To find object B I have done the following:

void OnTriggerEnter(Collider other)
    {
        if (other is BoxCollider && other.gameObject.CompareTag("Object"))
        {
            objectB = other.gameObject;
        }

To then try to call it later on -

void Update ()
{
if (objectB != null)
        {
            DoStuff();
        }
    }
}
void DoStuff()
    {
        print("Stuff is happening");
    }

This shows that whatever object A triggers becomes its reference. Is there something I can ask within the if statement to ask if the object is calling its Destroy function?

if
(objectB != null && objectB<GetComponent>IsBeingDestroyed())

Is of course invalid code.

@Baste , are you suggesting that I should look for the gameObject that the collider is attached to, or the collider itself? If I ask that the collider is null, it would call before even finding it. However, by using something like

//Construtor
bool neverDone = true;

//Within function
neverDone = false;

Would ensure it only calls once, so will bypass the clause that the collider is null in the first place.

Really appreciate the help.

It appears that I am close to being able to call when objectB is destroyed.

//Construtors
GameObject objectB

void Update()
{
if (objectB != null)
{
DoStuff();
}
}

void OnTriggerEnter(Collider other)
{
if (other is BoxCollider && other.gameObject.CompareTag("Object"))
{
objectB = other.gameObject;
}
}

void DoStuff()
{
print("Doing stuff");
}

Now when Object A collides with the trigger of Object B, it finds that objectB is not null, so calls DoStuff(). I need a way to access a component such as objectBIsBeingDestroyedScript(), in order to be called at the correct moment to call DoStuff().

I have looked through different answers, and most suggest not using within Update. Any ideas?

I have solved the problem. Thank you @Baste , @LeftyRighty for helping me out.