- Home /
Hey, I'm trying make an auto energy recovery system with my game (2D) with a while loop. I found that it crashes my unity and I need help in fixing it.
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class PlayerInfo : MonoBehaviour {
public int maxHealth = 8;
public int currentHealth;
public int maxEnergy = 8;
public int currentEnergy;
public HealthBar healthBar;
public EnergyBar energyBar;
//Timers
public IEnumerator RecoveryTime()
{
yield return new WaitForSeconds(10f);
RecoverEnergy(1);
Debug.Log("Plus 1");
}
public IEnumerator CoolDown()
{
yield return new WaitForSeconds(1f);
}
// Start is called before the first frame update
void Start()
{
currentHealth = maxHealth;
healthBar.SetMaxHealth(maxHealth);
currentEnergy = maxEnergy;
energyBar.SetMaxEnergy(maxEnergy);
}
// Update is called once per frame
void Update()
{
//Health Damage
if (Input.GetKeyDown(KeyCode.E))
{
TakeDamage(1);
}
//Energy Damage
if (Input.GetKeyDown(KeyCode.Space))
{
TakeEnergy(1);
StartCoroutine(CoolDown());
}
//Energy Recover
while (currentEnergy < maxEnergy)
{
StartCoroutine(RecoveryTime());
}
}
void TakeDamage(int damage)
{
currentHealth -= damage;
healthBar.SetHealth(currentHealth);
}
void TakeEnergy(int used)
{
currentEnergy -= used;
energyBar.SetEnergy(currentEnergy);
}
void RecoverEnergy(int recover)
{
currentEnergy += recover;
energyBar.SetEnergy(currentEnergy);
}
}
Comment
Answer by unity_ek98vnTRplGj8Q · Sep 04, 2020 at 08:29 PM
Update runs on the main unity thread, so if you have a while loop in your update method it will freeze unity until the while loop is done. Try putting the while loop in your coroutine instead.
private bool coroutineRunning = false;
//Replace the while loop in your update method
if ((currentEnergy < maxEnergy) && !coroutineRunning) {
StartCoroutine (RecoveryTime ());
}
public IEnumerator RecoveryTime () {
coroutineRunning = true;
while(currentEnergy < maxEnergy){
yield return new WaitForSeconds (10f);
RecoverEnergy (1);
Debug.Log ("Plus 1");
}
coroutineRunning = false;
}