0

I have to make a code where the cube disappears in a couple of seconds after the player touches it. But I have no idea how to make it because StartCoroutine(name()); works only in IEnumerator name(){} like this:

void Start()
{
    StartCoroutine(waiter());
}

IEnumerator waiter()
{    
    //Wait for 4 seconds
    yield return new WaitForSeconds(4);  
}

but I need to wait in private void OnCollisionEnter(Collision collision) {} function. I can't do something like this:

void start()
    {
        StartCoroutine(Text());
    }

    IEnumerator Text() 
    {
        private void OnCollisionEnter(Collision collision)
        {
            yield return new WaitForSeconds(3);
            StartCoroutine(Text());
            rd = GetComponent<Renderer>();
            rd.enabled = false;
        }
        

    }

How to make a cooldown in OnCollisionEnter function?

3
  • the trivial way to do things like this in Unity is simply the Invoke command. It couldn't be easier. Commented Dec 7, 2020 at 18:34
  • @Fattie to me Invoke has its good side and also a bad one: It is not cancelable. The Coroutine can still be stopped if e.g. the component is disabled in the meantime (let's e.g. say you open a Pause menu). The Invoke will be invoked after the time passed no matter what ;) Commented Dec 8, 2020 at 11:09
  • You know, there is actually a cancel-invoke believe or not! docs.unity3d.com/ScriptReference/… My point is just that for beginners, for trivial timers like this, you can just use "Invoke" - which is I'd say the very reason Unity tossed it in, make it easy for hobbyists ... Commented Dec 8, 2020 at 11:58

2 Answers 2

1
void Start() { }

private void OnCollisionEnter(Collision collision) {
    StartCoroutine(Text());
}

IEnumerator Text() 
{
    yield return new WaitForSeconds(3);
    rd = GetComponent<Renderer>();
    rd.enabled = false;
}
Sign up to request clarification or add additional context in comments.

Comments

1

Your nested methods make no sense.

Why not simply make OnCollisionEnter a Coroutine itself:

// Best you already reference this via the Inspector in Unity
[SerializeField] private Renderer _renderer;

private void Awake ()
{
    // Alternatively get it ONCE on runtime
    if(!_renderer) _renderer = GetComponent<Renderer>();
}

private IEnumerator OnCollisionEnter(Collision collision)
{
    yield return new WaitForSeconds(3);
   
    _renderer.enabled = false;
}

4 Comments

Isn't OnCollisionEnter auto-wired by Unity though? I thought it required a specific signature as it's called by rigid body in response to collision events - does it automatically get executed as a coroutine if you build the method signature to look like one (might be useful info for someone else)?
Yes, but if you make it IEnumerator it is automatically started as a Coroutine by Unity ;) Works with most event based messages except some exceptions like e.g. Awake, Update, OnDestroy .. but works with e.g. Start, OnTriggerEnter, OnCollisionEnter, OnTriggerExit, `OnCollisionExit, ...
That's useful info to know, I didn't find that in the docs
@Charleh yep it's pretty hidden ^^ see e.g. at the bottom of OnCollisionEnter -> OnCollisionEnter can be a co-routine, simply use the yield statement in the function. .. a bit confusing tbh it would be way better to understand if they would simply say ...simply let it return IEnumerator because that is what is ment actually ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.