I have this code in C# on a timer :

using Godot;
using System;

public class Timer : Godot.Timer
{
    bool dead=false;
    public override void _Process(float delta)
    {
        if (dead==false)
        {
            dead=true;
            GD.Print("Start");
            OneShot=true;
            WaitTime=2f;
            Start();
        }
    }
    void _on_Timer_timeout()
    {
        Stop();
        GD.Print("stop");
        dead=false;
    }
}

I stop the timer before returning the boolean value, but the timer continues.

Is this due to the _process loop running at the same time?

If anyone has a solution or an explanation.

Thanks in advance

  • SnapCracklins replied to this.
  • pcpunch59 I'll be honest, I don't use timers for things like this unless it's like a cutscene. Attaching the timer to process is probably the cause as @cybereality said.

    Personally, I make a value that changes every frame and once it "empties," I do the logic change.

    I program in GDScript, but maybe you'll get the jist of how I do it. It's essentially a manual timer but you're controlling every step of the logic. Give it a clear start and end. Have the value fill in process until your bool flips then stop. Note I am exporting these values to the editor so you can make fine tuned adjustments.

    var _timeElapsed = 0
    export var _timeGoal = 100
    export var _timeRate = 0.5
    var _canTrigger = false
    
    ## process loop for "filling" value/time
    func _process(_delta):
          if !_canTrigger:
                var _timeMath = _timeElapsed+_timeRate
                _timeElapsed = _timeMath
    
    ### this step controls the logic
         if _timeElapsed = _timeGoal:
             _canTrigger = true

    That's how I apply it. I am sure you are clever enough to figure it out. 😉

    What is the purpose of the timer? I.e., what are you trying to do?

    Process is called every frame, so you are continuously restarting the timer. The logic doesn't make sense.

    In fact I would like to do something like a coroutine in C# with unity, I would like the timer to start once when my boolean variable goes to true, and goes back to false at the end of the timer.

    Is the timer's purpose to toggle the variable "dead" every two seconds?

    To set a value to a node once I believe you can do it in the ready function and tree_entered signal, this way it only starts once, or you can set a check in the process function or a custom signal, to start the timer only when that condition is met.

    pcpunch59 I'll be honest, I don't use timers for things like this unless it's like a cutscene. Attaching the timer to process is probably the cause as @cybereality said.

    Personally, I make a value that changes every frame and once it "empties," I do the logic change.

    I program in GDScript, but maybe you'll get the jist of how I do it. It's essentially a manual timer but you're controlling every step of the logic. Give it a clear start and end. Have the value fill in process until your bool flips then stop. Note I am exporting these values to the editor so you can make fine tuned adjustments.

    var _timeElapsed = 0
    export var _timeGoal = 100
    export var _timeRate = 0.5
    var _canTrigger = false
    
    ## process loop for "filling" value/time
    func _process(_delta):
          if !_canTrigger:
                var _timeMath = _timeElapsed+_timeRate
                _timeElapsed = _timeMath
    
    ### this step controls the logic
         if _timeElapsed = _timeGoal:
             _canTrigger = true

    That's how I apply it. I am sure you are clever enough to figure it out. 😉

    I thought using a timer was appropriate for pausing a game.
    With unity I use a coroutine, example:

    bool dead=false; //if true wait 
        float delay=2f; 
        
        void Update()
        {
            //for testing
            if (Input.GetKeyDown(KeyCode.Space)) StartCoroutine(Wait_delay());
        }
    
        IEnumerator Wait_delay()
        {
            print("Start");
            dead = true;
            yield return new WaitForSeconds(delay);
            dead= false;
            print("End");
            //do something
    
        }

    So I did this with godot, but is this the best approach?

    bool dead=false; //
        float delay=2000, target_time;  
    
        public override void _Process(float delta)
        {      
            if(dead && Time.GetTicksMsec()>=target_time)   
            {
                dead=false;    
                GD.Print("End");
                //Do something
            } 
            //Test
            if(Input.IsActionJustPressed("ui_accept")) StartCountdown();
        }
    
        void StartCountdown(){  
            target_time = Time.GetTicksMsec()+delay; 
            dead=true;
            GD.Print("Start");       
        }