I'm trying to create a stamina system that loses x amount of stamina when attacking and after 5 seconds the lost stamina is regenerated, but I can't make it so that when the function is called several times, the previous calls are deleted and only last call left
this is my function
Debug.Log("Etapa 0");
if(currentStamina <= maxStamina){
StartCoroutine(TimerStamina());
Debug.Log("Etapa 1");
}
IEnumerator TimerStamina(){
yield return new WaitForSeconds(5);
StartCoroutine(RestartStamina());
Debug.Log("Etapa 2");
}
IEnumerator RestartStamina()
{
for(int x = 1; x <= maxStamina; currentStamina ){
Debug.Log("Etapa 3");
yield return regenTick;
if(currentStamina > maxStamina)
{
yield break;
}
}
Debug.Log("Estas cansado");
Debug.Log("Etapa 5");
}
I have tried several things but no result, so surely something is wrong with the way I am approaching this
CodePudding user response:
So if I understand correctly you want that no matter how often you hit attack, the stam regeneration only starts 5 seconds after the last attack.
There are probably many many ways to achieve this.
For instance I wouldn't use a routine at all but simply have a timer and restart it in Update
like
private float regenTimer;
public void Attack()
{
...
currentStamina -= someAmount;
regenTimer = initialDelay;
}
private void Update()
{
regenTimer -= Time.deltaTime;
if(regenTimer <= 0 && currentStamina < maxStamina)
{
currentStamina = Mathf.Min(currentStamina regenAmountPerSeconds * Time.deltaTime, maxStamina);
}
}
or if it is not float
but rather int
then you could have two timers
private float regenTimer;
private float regenTickTimer;
public void Attack()
{
...
currentStamina -= someAmount;
regenTimer = initialDelay;
regenTickTimer = regenTickDelay;
}
private void Update()
{
regenTimer -= Time.deltaTime;
if(regenTimer <= 0 && currentStamina < maxStamina)
{
regenTickTimer -= Time.deltaTime;
if(regenTickTimer <= 0)
{
currentStamina = regenAmountPerTick;
regenTickTimer = regenTickDelay;
}
}
}
If you rather want to go for a Coroutine you could store and cancel it when needed e.g.
private Coroutine regenRoutine;
public void Attack()
{
...
currentStamina -= someAmount;
if(regenRoutine != null) StopCoroutine(regenRoutine);
regenRoutine = StartCoroutine(RegenRoutine());
}
private IEnumerator RegenRoutine()
{
yield return new WaitFoSeconds(initialDelay);
while(currentStamina < maxStamina)
{
currentStamina = regenAmountPerSecond * Time.deltaTime;
yield return null;
}
}
again in case it is rather int
private IEnumerator RegenRoutine()
{
yield return new WaitFoSeconds(initialDelay);
while(currentStamina < maxStamina)
{
yield return new WaitForeconds(tickDelay);
currentStamina = regenAmountPerTick;
}
}