I'm after some conceptual assistance. The problem: I have a sequence of actions which occur in a turn-based game. A common 'round' might be something like: 1. Ask the player to PRESS A to move 2. Wait for the player to select a target location 3. Move the avatar to the target location 4. Display a short "You have reached your destination" type message 5. Wait for the player to PRESS A to continue 6. Move to the next player and repeat The individual logistics of each task don't give me any trouble, but the overall conceptual framework for structuring this code, does. I have a GameManager singleton which tracks pretty much everything, and I would like to keep most of the gameplay-type stuff encapsulated here, with individual units and such just data containers. Unless someone proposed an alternative, of course. At the moment, I'm pretty much 'brute forcing' the solution: switch (m_gameState) { case GameState.WaitForA: ... case GameState.WaitForTargetSelect: ... case GameState.MoveAvatarToLocation: ... case GameState.WaitForAAgain: ... case GameState.SelectNextPlayer: ... } In a short example like this, it's not that bad. But when I start introducing potentially repetetive and overlapping 'game states', such as the option to Pause at any time, or frequent requests to Press A To Continue, the need to wait for animations to finish, etc., it turns into spaghetti in my head and I end up staring at my screen for 20 minutes without typing anything. I guess what I'm asking is: How would you recommend I manage my states? How should I divide them up into multiple, layered states? Should I make some super cool use of coroutines (just discovered them, love them to bits) to manage this? Does anyone have any in-depth game state examples they wouldn't mind sharing? I'd love any anecdotal advice that could be offered. Thanks for any help, it's appreciated.
I guess that's all in Update? Coroutines would simplify things massively. Your list could be written like: Code (csharp): function GameLoop () { while (true) { for (i = 0; i < numberOfPlayers; i++) { yield WaitForAButton(); yield PlayerSelectTargetLocation (i); yield PlayerMove (player[i].position, target[i].position); DisplayMessage ("You have reached your destination"); yield WaitForAButton(); } } } --Eric
Awesome, thanks for the fast reply! I'll need to do some more reading on Coroutines to understand how they work. At the moment I've got a problem I'm trying to solve myself, but I can't see what I've done wrong compared to examples: I have the following method. It is called once with StartCoroutine(GameLoop()). Every Debug.Log() prints as expected to the console: Code (csharp): private IEnumerator GameLoop() { Debug.Log("GameLoop started!"); Debug.Log("Player count = " + PlayerCount); for(int i = 0; i < PlayerCount; i++) { Debug.Log("Calling MainCamera.Instance.MoveToTarget(" + m_players[i] + ", 2.0f)"); yield return MainCamera.Instance.MoveToTarget(m_players[i], 2.0f); } } However, the very first Debug.Log() in this code does not print to console (this method is located in the MainCamera monobehaviour). Code (csharp): // Move the camera to the specified player's position. public IEnumerator MoveToTarget(Player player, float duration) { Debug.Log("MoveToTarget() called..."); Vector3 srceLoc = transform.position; Vector3 destLoc = player.transform.position; if (duration <= 0.0f) duration = 0.0f; bool repeat = true; float transition = 0.0f; while (repeat) { if (transition >= 1.0f) { repeat = false; transition = 1.0f; } transform.position = Vector3.Slerp(srceLoc, destLoc, transition); transition += (1.0f / duration) * Time.deltaTime; yield return 0; } } I can't see why the code isn't executing correctly. I'm expecting it's something very simple that eludes me.
You'll need to execute the subsequent Coroutines with StartCoroutine too: Code (csharp): yield return MainCamera.Instance.StartCoroutine(MoveToTarget(m_players[i], 2.0f));