![]() |
BomberUnits
...a Unity learning project
|
We need a program control flow which is as simple as possible while being inspectable and extendable.
The control flow over a Unity game is based primarily on the Unity "MonoBehaviour" Callbacks. This means the engine simulates the progression of time in-game, executing a number of execution cycles each second (corresponding to the power of the executing machine) called Frames.
Each frame, control is handed one after another to the active Behaviors, i.e. Scripts attached to game objects instantiated in a given scene. Another category of objects receiving callbacks are Behaviors attached to the states of an (Animator) state machine.
This concept leaves the order of execution entirely to the engine, with the designer only knowing that their script (MonoBehaviour, StateMachineBehaviour) will be executed eventually, according to the Callbacks re-implemented in those scripts: Update() etc...
With the control flow being inherently highly parallel and with an unknown sequence, the remaining design decision is how all these scripts should interact with each other and with other classes and their instances not derived from Behaviours.
There are a number of re-occurring important tasks, such as managing the overall program state, keeping track of the network state, the UI etc...
This leads to a number of GameManagement components attached to invisible management GameObjects. These provide the interface or access to a component having the interface to affect the global game behaviour.
The control flow from Events, such as User Input, Network or In-Game events, should go from the receiving entity to the affected management component.
Example: User Control Flow:
User input -> UI Management -> Distribution to other components as per domain.
E.g: Creation of a new local player via UI -> UI Management is given the new player -> Player Management logs and keeps track of it and triggers
Example: Network Event Control Flow:
Network Event -> Network Management -> Distribution to other components as per domain.
E.g: The connection is dropped -> Network Management receives event -> informs Game Management about the
issue -> Game Management causes all kinds of actions, e.g. pausing and waiting for a reconnect.
We want visually scriptable and inspectable state machines to represent management states for the above domains and carry out actions. The reactive behaviour of a management component to a change in state is thus allocated with the affected state of the state machine.
Have a look at the Handling State page for details on the existing state machines.
Each state machine can trigger actions when their state transitions. State machines are never accessed directly though, but through an abstraction layer by their holding Behavior (Management component).
We need the following pairs of management domains with state:
For access to the important management Behaviours, these are to be instantiated as singletons. We deviate a bit from the pattern, in that we have the single instance be created by the engine (attachment of the script as component).
The Unity-native Animator State Machine feature is to be used to implement the state machines. This enables visual editing, introspection and event handling. Have a look here for details: How to create state machines
Have a look here for background info on the startup: How to startup Behaviours
Using the Callbacks explained there in combination with State Machines is used to 'boot' the game to its initial state in the main menu. See here for details: The Game Startup
Here are the relevant management classes, implementing the above concepts. They are accessible as singletons:
See here for an overview of the existing state machines, and how to use them: Handling State