Why are the CoRoutines not stopping?
Basically I have a 2D game that is like the old Zeldas: two connected rooms with a controllable player.
I have defined two Collision2D triggers between the two rooms in order to load the things I need:
One, executed ONCE on entering room B from room A, to execute the routines for spawning enemies and start a timer.
And another one, executed ONCE on exiting room B to room A, that actually stops the routines previously created.
This is the script that both Collision2D objects inherit, including the routines:
public class RoomTransferController : MonoBehaviour
{
...
private IEnumerator spawn;
private IEnumerator timer;
void Start()
{
spawn = AddEnemy();
timer = CreateTimer();
...
}
private void OnTriggerEnter2D(Collider2D other) {
if (other.gameObject.CompareTag("Player") && this.gameObject.CompareTag("TrialEnter") && other.isTrigger)
{
StartCoroutine(spawn);
StartCoroutine(timer);
}
if (other.gameObject.CompareTag("Player") && this.gameObject.CompareTag("TrialExit") && other.isTrigger)
{
StopCoroutine(spawn);
StopCoroutine(timer);
}
}
private IEnumerator AddEnemy()
{
while (true)
{
int rnd = UnityEngine.Random.Range(0, 5);
// spawnPoints is just a Vector2[]
Instantiate(prefabEnemy, spawnPoints[rnd], Quaternion.identity);
yield return new WaitForSeconds(5f);
}
}
private IEnumerator CreateTimer()
{
int currentTime = 0;
while(true)
{
currentTime += 1;
// elapsedTime is a Text object
elapsedTime.text = currentTime.ToString();
yield return new WaitForSeconds(1f);
}
}
}
The script looks perfectly fine but when executing the game, the routines do not stop when exiting room B. It actually enters in the condition from OnTriggerEnter2D, but it seems to ignore the StopCoroutine method.
I tried to set spawn and timer variables every time StartCoroutine is called in order to not be null when calling StopCoroutine, but it does not solve it.
I also tried to make a State Machine, that when entering or exiting room B, it will update isPlayerInTrial and depending on its value, it will stop the routines in Update:
public enum TrialState {
wait,
enter,
exit
}
public class RoomTransferController : MonoBehaviour
{
private TrialState isPlayerInTrial;
...
void Start()
{
isPlayerInTrial = TrialState.wait;
spawn = AddEnemy();
timer = CreateTimer();
...
}
void Update()
{
if (isPlayerInTrial == TrialState.exit)
{
StopCoroutine(spawn);
StopCoroutine(timer);
isPlayerInTrial = TrialState.wait;
}
}
private void OnTriggerEnter2D(Collider2D other) {
if (other.gameObject.CompareTag("Player") && this.gameObject.CompareTag("TrialEnter") && other.isTrigger)
{
isPlayerInTrial = TrialState.enter;
StartCoroutine(spawn);
StartCoroutine(timer);
}
if (other.gameObject.CompareTag("Player") && this.gameObject.CompareTag("TrialExit") && other.isTrigger)
{
isPlayerInTrial = TrialState.exit;
}
}
// AddEnemy() and CreateTimer() routines
}
But again, the same result yielded from this approach. Where can I be wrong? Am I not understaing how StopCoroutine works?
Your answer