Continious decrease going on but I want timed

I want to make my “Energy” variable Wait 3 seconds and then decrease the energy,
but what happens is it waits 3 seconds for the first time, and then decreases the energy
very fast like its some stupid mad guy. I even tried it to do something like:

“Make another function for reduction, and make it call the first part, then make the second part call the other.”

If you think its Marco-Polo or something, no you’re wrong. the thing is

THIS:

var Energy = 100;
var EnergyLoss = 1;
var EnergyLossTiming = 10; 

function Update()
{

//A very long Update() code to make the player move

HealthConfidenceNRGTimer();
}

function HealthConfidenceNRGTimer()
{
yield WaitForSeconds(EnergyLossTiming);
HealthConfidenceNRG();	
}
function HealthConfidenceNRG(){
Energy -= EnergyLoss;
HealthConfidenceNRGTimer();
Debug.Log("Energy reduced to" + Energy);}

P.S- I have done all I could.

Thanks!

That’s some slightly funky code right there. I’m a c# coder so I can’t tell you exactly why its having the result you’re seeing, but the code’s definitely not right!

You are effectively doing recursion there. You are calling the timer function, which calls the nrg function, which calls the timer function, which calls the nrg function etc etc forever and ever!

You’re also doing that recursive yield from within the update function - I’m not sure what the consequences are. You probably want a coroutine that looks more like this:

var Energy = 100;
var EnergyLoss = 1;
var EnergyLossTiming = 10; 
 
function HealthConfidenceNRGTimer()
{
    while(true)
    {
        yield WaitForSeconds(EnergyLossTiming);
        HealthConfidenceNRG();  
    }
}

function HealthConfidenceNRG()
{
    Energy -= EnergyLoss;
    Debug.Log("Energy reduced to" + Energy);
}

There you have a while loop that will wait for x seconds, then decrement health, then loop around and do the same. Of course because its while(true) it’ll go on forever - I’d imagine you’d want to avoid that with some condition that depends on your game.

I also suspect that you will need to do this by calling StartCoroutine(HealthCondifenceNRGTimer) from your start function, rather than calling it from the update function.

Alternatively, you could do away with the coroutine altogether and just do something like:

var Energy = 100;
var EnergyLoss = 1;
var EnergyLossTiming = 10; 
var LastEnergyLossTime = 0;

function Update()
{
    if((Time.time-LastEnergyLossTime)>EnergyLossTiming)
    {
        HealthConfidenceNRG();  
        LastEnergyLossTime = Time.time;
    }
}

function HealthConfidenceNRG()
{
    Energy -= EnergyLoss;
    Debug.Log("Energy reduced to" + Energy);
}

Or even make it go down gradually but continuously…

    var Energy = 100;
    var EnergyLossPerSecond = 1;
    
    function Update()
    {
        //decrease energy by a tiny amount every frame, based on the amount of time that passes in a single frame
        Energy -= EnergyLossPerSecond * Time.deltaTime;
    }

Hope that helps!

Use proper Coroutine methods. No need of Update function. This is the C# version of you requirement. Only minor declaration tweaks would be required to convert it to JavaScript. Enjoy :slight_smile:

	public int EnergyLoss=1;
	int Energy = 100;
	float EnergyLossTiming = 10; 
	
	void Start()
	{
		StartCoroutine (HealthConfidenceNRGTimer());
	}
	
	IEnumerator HealthConfidenceNRGTimer()
	{
		//Inifnite loop just to act like Update function
		for(;;)
		{
			yield return new WaitForSeconds(EnergyLossTiming);
			HealthConfidenceNRG();  
		}

	}
	void HealthConfidenceNRG()
	{
		Energy -= EnergyLoss;
		
		Debug.Log("Energy reduced to" + Energy);
	}