Is this correct way of 'refreshing' Coroutine?

If player attacks my object, its ‘Struck’ method will push it in some direction.

Coroutine ‘RecentlyStruck’ is assigned to struckCorutine variable, coroutine keeps track of recentlyStruck bool which I need for other methods.

If another player attacks this object while struckCoroutine is not null, current coroutine will be stopped and replaced with new one. (Resseting timer)

Here’s my question: Is this clean way of doing this?

I am doing projects for my github so I want this to be efficient and not complicated for no reason.

(Its simple example, I am using similar technique of ‘refreshing’ for more advanced stuff)

public void Struck(Vector3 direction, float strength)
    {
        idleTimer = idleTimeToCast;
        rb.AddForce(direction * strength, ForceMode.VelocityChange);
        if (struckCoroutine != null) DisableStruck();
        struckCoroutine = StartCoroutine(RecentlyStruck());


    IEnumerator RecentlyStruck()
    {
        yield return new WaitForSeconds(recoverDuration);
        recentlyStruck = false;
        struckCoroutine = null;
    }

    void DisableStruck()
    {
        StopCoroutine(struckCoroutine);
        struckCoroutine = null;
    }

(StopCoroutine doesn’t make struckCorutine a null so this is why I am setting it to a null at the end)

If you’re just implementing a cooldown timer, using coroutines is WAAAAAY too complicated.

Make a float for the “RecentlyHit” time, and when you get hit, assign the cooldown delay to that variable.

In Update() count it down by Time.deltaTime, and don’t let anything happen if RecentlyHit is greater than zero.

No coroutines, no code paths to keep track of, no coroutines to stop (always a huge source of bugs). etc.

1 Like

For this one I will switch to using timer, but as I said, I have different couroutines that are much more advanced and I need to have a way to ‘refresh’ them.
I posted this one to explain my problem easier (less wall of text).

The way you’re doing it is correct, but unless you’re doing something else with the coroutine variable, you don’t need to explicitly set it to null – you can just reassign it to the new coroutine. This is the pattern I use in my code:

if( coroutine != null ) StopCoroutine( coroutine );
coroutine = StartCoroutine( MyCo() );
1 Like