Fill up and empty meter

i have a meter that i want my player to fill up by tapping the space button = works fine.

But i also want the meter to reduce simultaneously if the player is too slow = having problems with

here is my code:

function Update () 
{
	if( Input.GetKeyUp(KeyCode.Space) )
	{
		Global_Counters.STONE_WALL_METER ++;
	}
	
	if( Global_Counters.STONE_WALL_METER < 9 )
	{
		ReduceMeter();
	}
}
	
function ReduceMeter()
{
	yield WaitForSeconds (2.0);
	
	if( !Input.GetKeyUp(KeyCode.Space) )
	{
		var x = Global_Counters.STONE_WALL_METER - 1; 
		if( x > 0 )
		{
			Global_Counters.STONE_WALL_METER --;
		}
	}
}

The primary problem is that you are calling ReduceMeter() in Update. Each time you call ReduceMeter() it creates a new coroutine that is then yielded. If you app was running at 60 fps, you would stack up 120 coroutimes before the first one fires, then one (or more) would approximately fire every frame for the rest of the game.

I’m having a hard time figuring out from the code you have here under what conditions the meter should be reduces, so I don’t know how to recommend a fix. You could:

  • Remove the yield and start an Invoke() repeating in Start().
  • Call ReduceMeter once and then execute the code inside in a forever loop (while(true)) inside ReduceMeter.
  • Use a time or timestamp.

My guess is that you want the last one. Something like this (untested):

var timeStamp : float;
var waitTime = 2.0;

function Start() {
	timeStamp = Time.time + waitTime;
}

function Update () 
{
    if( Input.GetKeyUp(KeyCode.Space) )
    {
       Global_Counters.STONE_WALL_METER ++;
       timeStamp = Time.time + waitTime;
    }
 
    if( Global_Counters.STONE_WALL_METER < 9  && timeStamp < time.Time)
    {
       ReduceMeter();
       timeStamp = Time.time + waitTime;
    }
}
 
function ReduceMeter()
{ 
       if( Global_Counters.STONE_WALL_METER > 1 )
       {
         Global_Counters.STONE_WALL_METER --;
       }
    }
}