Another (simpler?) timer

An alternative way to write a timer in Unity (and in my opinion much simpler) is with coroutines. It would be something like this (in EnemyAI):

// No need for Update function at all in this case.
void TurnSystem_OnTurnChanged() {
  if (TurnSystem.Instance.IsHumanTurn()) {
     return;
  }
  StartCoroutine(WaitAndEndTurn(2f));
}

IEnumerator WaitAndEndTurn(float waitTime) {
  yield return new WaitForSeconds(waitTime);
  TurnSystem.Instance.NextTurn();
}

Note though that coroutines are not threads - they still run in the main event loop on the same thread. Just every time yield is called, the control is given back to the event loop (somewhat like in cooperative scheduling) and it gets called again (continuing from where it yielded) the next time only when whatever condition we gave it has passed (or on the next frame if it was yield return null;).
IMO, they are oftentimes very useful for making the code less cluttered.

1 Like

Personally I really dislike coroutines, I find that pattern for be extremely obtuse and unintuitive, having to make a IEnumerator function, call StartCoroutine on a MonoBehaviour, etc.
So for me personally I am not a fan of that forced pattern so I never use Coroutines.

But yup the end result is the same, so if you like them then go ahead and use them.

2 Likes

It could be even simpler:

void NextTurn() => TurnSystem.Instance.NextTurn();
void TurnSystem_OnTurnChanged() => Invoke(nameof(NextTurn), 2f);

There are many ways to do the same thing. It all comes down to how readable and maintainable a specific solution would be in the long run

2 Likes

Oops, I forgot the “if” for checking if it is enemy turn in the first post, so using it directly would have resulted in the EnemyAI happily ending both player’s and enemy’s turn. Will fix.

Given it’s just a dummy stub implementation that’s soon to be replaced anyway, I wouldn’t actually put too much thought into it… :wink:

Its purpose is solely to implement the minimum amount of code for an “enemy” to take over and release control with a tiny delay (faking “I’m busy”) back to the player, so one doesn’t have to restart the game all the time just for testing, when the initial APs are used up.

Privacy & Terms