interrupting a timer

i have a collider that activates an event, and i would like the collider to activate only if it maintains contact for a few seconds before activating. how do i set a timer that waits for a while and is interrupted (and possibly resets) if the collider is no longer being activated? thank you for any help!

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

public class Event : MonoBehaviour
{
    [SerializeField] LayerMask DesiredMask;
    public UnityEvent TriggerEntered;
    public UnityEvent TriggerLeft;
    public float time;
    private Collider TriggerCollider;

    private void OnTriggerEnter(Collider other)
    {
        StartCoroutine("Waiting");
        if ((DesiredMask.value & (1 << other.transform.gameObject.layer)) > 0) //Look for desired layer
        {
            TriggerEntered.Invoke();
        }
    }

IEnumerator Waiting()
    {

        yield return new WaitForSeconds(time); // where time its a float

    }
IEnumerator Stop()
    {

        yield return null;

    }

    private void OnTriggerExit(Collider other)
    {
        if ((DesiredMask.value & (1 << other.transform.gameObject.layer)) > 0)
        {
            StartCoroutine("Stop");
        }
    }

If you save a reference of your Coroutine, you could always call StopCoroutine. I believe there’s a lot of people here who will say to not use Coroutines for something like this though.

Maybe an easier way would just to set a value to true/false, and keep track of a timer inside of Update.

Would you be paging me RadRedPanda? :slight_smile:

Yes, my criteria is if you ever even consider needing to call StopCoroutine() then what you are doing should NOT be a coroutine.

For the specific case of what @itisemtea speaks I would reach for a simple float timer.

I do this all the time in my games to decide if you have “dwelled” long enough for something to activate.

private float inContactTimer;
private const float contactTimeRequired = 1.0f;

and in your Update():

if (InContact())
{
  inContactTimer += Time.deltaTime;

  if (inContactTimer >= contactTimeRequired)
  {
    inContactTimer = 0;
    Debug.Log( "I consider you to have been in contact for long enough.");
  }
}
else
{
  // reset
  inContactTimer = 0;
}

This is just used EVERYWHERE in gaming… and it’s all used just a little differently:

  • count up?
  • count down?
  • count individual items (integer?), etc.
  • allow it to happen multiple times if you stay long enough?
    etc

For instance you see it here: you need to be in contact with a base and stationary for 0.1s before it trips you as “captured and refueled”:

https://www.youtube.com/watch?v=V8ABCkZe32c