Data structures

GameController

 * Center piece of the scripts.
 * Is a singleton attached to GameController prefab in the PersistentScene scene.
 * Singleton is accessed via GameController.Instance;
 * Stores references to objects other scripts might need.
 * These references are accessible via the class'es properties. These are read-only.
 * ie: GameController.Instance.PlayerController.Heal(0.25f);
 * GameController calls each eligible reference'es Init methods in it's Start method. This allows precise control over initialization order.
 * References stored in the instance must be initialized via it's SetReference method. The method is to be called on Awake in the script of the object you wish to store a reference to.
 * ie: Setting the reference to PlayerController and initializing it.
 * Program starts. =>
 * PlayerController's Awake is called. =>
 * PlayerController requests it's reference to be set in the GameController. =>
 * GameController sets it's reference. =>
 * Time passes. =>
 * GameController's Start is called. =>
 * GameController calls the Init of PlayerController.
 * public bool SetReference(Monobehaviour caller) returns true if the reference has been successfully set, false if it encoutered an issue. Use this to throw errors.

EventManager

 * Centralizes all causality relationships, improving modularity.
 * Attached to GameController prefab in the PersistentScene scene.
 * Accessed via the GameController.
 * ie: GameController.Instance.EventHandler;
 * Defines custom events. Each new event type needs three things to be defined:
 * An enum value in EventType enum.
 * A delegate type from which to make an event from.
 * An event created from the delegate type publicly accessible to store callbacks in.
 * Events are triggered via TriggerEvent.
 * ie: Sending a stepped in fire event: GameController.Instance.EventHandler.AddEvent(EventType.STEPPED_IN_FIRE);
 * Callbacks are to be added to the instance'es public event attributes. They all begin with "On".
 * ie: GameController.Instance.OnDeath += DisplayGameOver;
 * Use example: Tutorial teaching the player to move:
 * Text showing movement controls is displayed. =>
 * Player presses the move button =>
 * InputHandler detects input and creates a MOVE event via AddEvent. =>
 * InputHandler invokes all callbacks stored in OnMove. =>
 * PlayerController's Move callback is invoked AND TutorialController's Move callback is invoked. =>
 * PlayerController's Move calls PlayerMovementController's Move AND PlayerAnimationController's Move.
 * At the same time TutorialController's Move callback changes tutorial's stage from AWAITING_INPUT to TRANSITION_TO_NEXT_STAGE.

InputManager

 * Centralizes all inputs, improving modularity.
 * Attached to GameController prefab in the PersistentScene scene.
 * Sends input messages to concerned scripts via the EventManager.
 * ie: Jump button
 * Player presses the jump button. =>
 * InputManager detects it and sends a JUMP event. =>
 * PlayerController recieves the event and calls it's Jump private function.
 * Has three operating states:
 * GAME: Applies main game's control scheme.
 * MENU: Applies the menu's control scheme.
 * ie: ENTER to press menu button, UP_ARROW to select button above, etc.
 * CUTSCENE: Applies the cutscene's control scheme.
 * ie: ESC to skip the cutscene.

SceneManager

 * Manages scene transitions.
 * There is one PersistentScene in the game. It has the Main Camera and the GameController prefab.
 * Scene transitions in this game are done additively as to avoid loading times.
 * LoadSceneAsync and UnloadSceneAsync are used to transition between scenes seamlessly. They send events on loading/unloading start and end.

CameraController

 * Controlls the movements of the camera.
 * Attached to MainCamera GameObject in the PersistentScene scene.
 * Has three operating modes:
 * GAME: Relays control of the camera to the Cinemachine script.
 * MENU: Camera is static.
 * CUTSCENE: The camera traverses the Cutscene sequence.

PlayerController

 * Controller class interfacing with the rest of the game's system.
 * Gets objects needed by player's components and initializes the components when it's Init function is called by the GameController on Start.
 * Calls player component's appropriate public methods upon various events.
 * ie: Player's jump
 * PlayerController's Init function is called by GameController. =>
 * Init adds Jump callback to GameController.EventHandler.OnJump event.
 * Some time passes =>
 * PlayerController's Jump function is invoked by the EventHandler.
 * Jump calls PlayerMovementComponent's Jump function AND PlayerAnimationComponent's Jump function.

PlayerMovementComponent

 * Controls only the movement physics of the player. This includes:
 * Walking and Running
 * Jumping
 * Swinging on gum
 * Requests input data upon reception of an input event from the InputHandler.
 * ie: Moving player to the right.
 * PlayerMovementController recieves a HORIZONTAL_INPUT event. =>
 * PlayerMovementController updates it's _horizontalInput variable and waits. =>
 * Some time passes. =>
 * FixedUpdate is called. =>
 * PlayerMovemementController applies a force to the player's rigidbody using _horizontalInput variable.

Diagrams

 * Composition Diagram:ClassDiag.png
 * Script Initialization Order: Initialization order.png