Reset a timer for a power up

Hi.
i need help with reset the timer of the coroutine i made for a powerup called “speed_pepper”
i tried with invoke and cancel invoke but it also dont work.

here is the code:

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

public class speedpeper : MonoBehaviour
{

    /////// vars ///////
    
    


    private static bool is_peper_active;
    
    void Start()
    {
        
    }

    
    void Update()
    {
        peper_movement();
        
    }

    // trigger speed peper 
    public void OnTriggerEnter2D(Collider2D other)
    {
        UI_manager uI_Manager;
        uI_Manager = FindObjectOfType<UI_manager>();

        player player;
        player = FindObjectOfType<player>();

        if (other.tag == "Player")
        {
            if (is_peper_active == false)
            {
                uI_Manager.add_score();
                is_peper_active = true;
                player.player_speed = 9;
                transform.position = new Vector2(0,800);
                StartCoroutine("speed_peper_deactive");
                Destroy(gameObject,80);
                Debug.Log(is_peper_active);
            }
            else if(is_peper_active == true)
            {   
                uI_Manager.add_score();
                player.player_speed = 9;
                transform.position = new Vector2(0,800);
                StopCoroutine("speed_peper_deactive");
                StartCoroutine(speed_peper_deactive());
                Destroy(gameObject,80);
                Debug.Log("it works");
            }
            
        }
        else if (other.tag == "floor")
        {
            Destroy(gameObject);
        }
    }
    private void peper_movement()
    {
        transform.Translate(Vector2.down * 3.5f * Time.deltaTime);

    }


    //cancel speed peper buff
    private IEnumerator speed_peper_deactive()
    {
        player player;
        player = FindObjectOfType<player>();
        
        yield return new WaitForSecondsRealtime(10);
        
        is_peper_active = false;
        player.player_speed = 6;
    }


}

Hello mate,

I don’t really know why you use a Coroutine since your Update method is enough to do something like that:

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

public class speedpeper : MonoBehaviour {

    /////// vars ///////

    private static float PEPER_COOLDOWN = 10; // 10s cooldown

    private float _peperTimer;
    private bool _isPeperActive;
    private player _player;
    private UI_manager _uiManager;

    void Update() {
        peper_movement();

        // Check the timer if the peper is active
        if (this._isPeperActive == true) {
           this.CheckPeperTimer();
        }
    }

    private void CheckPeperTimer() {
        if (this._peperTimer <= Time.time) {
           this.DeactivatePeperEffect();
        }
    }

    // trigger speed peper 
    public void OnTriggerEnter2D(Collider2D other) {
        if (other.tag == "Player") {
           if (this._player == null) {
              // keep a reference on the player (for opti)
              this._player = other.GetComponent<Player>(); 
           }

           this.ActivatePeper(); // launch the peper effect
        } else if (other.tag == "floor") {
            Destroy(gameObject);
        }
    }

    private void peper_movement() {
        transform.Translate(Vector2.down * 3.5f * Time.deltaTime);
    }

    private void DeactivatePeperEffect() {
        this._player.player_speed = 6;
        this._isPeperActive = false;
    }

   private void ActivatePeper() {
        if (this._uiManager == null) {
           this._uiManager = FindObjectOfType<UI_manager>();
        }

        this._uiManager.add_score();

        this._player.player_speed = 9;
        transform.position = new Vector2(0,800);

        this._peperTimer = Time.time + PEPER_COOLDOWN;
        this._isPeperActive = true;

        Destroy(gameObject, 80);
   }

}

If you still want to know about the Coroutine: you can store it in a variable:

private Coroutine _myCoroutine;

private void MyFunction() {
    this._myCoroutine = StartCoroutine(MyCoroutine());
}

private void StopMyCoroutine() {
    StopCoroutine(this._myCoroutine);
}

I see a couple issues with your code:

  1. is_peper_active probably should not be made static. This causes is_peper_active to affect all speedpepers in the scene.

  2. If you want to stop a co-routine, you need to start and stop it with a string, not the IEnumerator.

You should replace

StartCoroutine(speed_peper_deactive());

with

StartCoroutine("speed_peper_deactive");

Ex: This code will not stop the co-routine:

StartCoroutine(speed_peper_deactive());
StopCoroutine("speed_peper_deactive");

actually if it is not static it will change to false every time its instantiate so i had to use it as a static var

and i also tried to put it with a string and it duos not work.

i do have 2 speedpeper ill try to change it

so i have a solution

big shoutout to Lasmus Dev from stackoverflow and cyber_cats for helping me get to the solution (and everynody els that took time from there life to help a random beginner online) <3

public static float activeTimer = 10f;

    private static IEnumerator speed_peper_deactive()
    {
        player player;
        player = FindObjectOfType<player>();

        do
        {
            activeTimer -= Time.deltaTime;
            yield return null; //Wait for next frame, then update timer again.
            Debug.Log(activeTimer);
        }
        while (activeTimer > 0);
        player.player_speed = 6;
        is_peper_active = false;
    }


}

i did a timer that will be added with more time every time a speedpeper taken
the problem with the last method wasn’t the “static” or something like that, it was that every time another speedpeper was taken it didn’t cancel the first coroutine i actually still don’t know how to cancel it (and i tried like 3 different methods of stopcoroutine and even with invoke and cancelinvoke) so IDK what was the problem (and any ai or a forum i asked on lol)