From cc5458b51e14829daa282993c04452e2de3432bd Mon Sep 17 00:00:00 2001 From: erheine <erheine@nps.edu> Date: Tue, 24 Mar 2020 10:26:13 -0700 Subject: [PATCH] Added a class that fires game events based on its current state. --- State Manager.meta | 10 +++ State Manager/Shared.StateManager.asmdef | 15 ++++ State Manager/Shared.StateManager.asmdef.meta | 7 ++ State Manager/State.cs | 32 ++++++++ State Manager/State.cs.meta | 11 +++ State Manager/StateManager.cs | 76 +++++++++++++++++++ State Manager/StateManager.cs.meta | 11 +++ package.json | 2 +- 8 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 State Manager.meta create mode 100644 State Manager/Shared.StateManager.asmdef create mode 100644 State Manager/Shared.StateManager.asmdef.meta create mode 100644 State Manager/State.cs create mode 100644 State Manager/State.cs.meta create mode 100644 State Manager/StateManager.cs create mode 100644 State Manager/StateManager.cs.meta diff --git a/State Manager.meta b/State Manager.meta new file mode 100644 index 0000000..fe7ec35 --- /dev/null +++ b/State Manager.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a51ef5da8031fd141a078805d54ccb66 +folderAsset: yes +timeCreated: 1510599145 +licenseType: Pro +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/State Manager/Shared.StateManager.asmdef b/State Manager/Shared.StateManager.asmdef new file mode 100644 index 0000000..44340e4 --- /dev/null +++ b/State Manager/Shared.StateManager.asmdef @@ -0,0 +1,15 @@ +{ + "name": "Shared.StateManager", + "references": [ + "GUID:6735fe1fe1dbd994a96eb9d888b81400" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/State Manager/Shared.StateManager.asmdef.meta b/State Manager/Shared.StateManager.asmdef.meta new file mode 100644 index 0000000..57cd66d --- /dev/null +++ b/State Manager/Shared.StateManager.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: bf6ca905532d08647bc1c0964551b0f5 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/State Manager/State.cs b/State Manager/State.cs new file mode 100644 index 0000000..8278e89 --- /dev/null +++ b/State Manager/State.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using UnityEngine; +using Shared.ScriptableVariables; + +namespace Shared.StateManager { + // A scriptable object that represents one state a StateManager can be in + [CreateAssetMenu(menuName = "Scriptable Objects/State")] + public class State : ScriptableObject { + [Tooltip("The GameEvent that will switch a StateManager into this State")] + public GameEvent enterEvent; + + [Tooltip("The list of GameEvents to fire when this State gets activated")] + public List<GameEvent> inEvents = new List<GameEvent>(); + + [Tooltip("The list of GameEvents to fire when this State gets deactivated")] + public List<GameEvent> outEvents = new List<GameEvent>(); + + // ------------------------------------------------------------------------ + public void EnterState() { + foreach (var inEvent in inEvents) { + inEvent?.Raise(); + } + } + + // ------------------------------------------------------------------------ + public void ExitState() { + foreach (var outEvent in outEvents) { + outEvent?.Raise(); + } + } + } +} diff --git a/State Manager/State.cs.meta b/State Manager/State.cs.meta new file mode 100644 index 0000000..0b5da36 --- /dev/null +++ b/State Manager/State.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f4ee41ed730737741b3c93effc4fb5a9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/State Manager/StateManager.cs b/State Manager/StateManager.cs new file mode 100644 index 0000000..9a0575c --- /dev/null +++ b/State Manager/StateManager.cs @@ -0,0 +1,76 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using Shared.ScriptableVariables; + +namespace Shared.StateManager { + // Manages what State is currently active in a given scene + public class StateManager : MonoBehaviour { + [Tooltip("The state we should start out with when this manager is enabled")] + public State startingState; + + [Tooltip("The list of possible states this component is managing")] + public List<State> possibleStates = new List<State>(); + + [Tooltip("The currently active state for this manager")] + [SerializeField] + private State currentState; + + // A list of delegates the possible states are listening to for entering so + // we can stop listening on disable + private Dictionary<State, GameEvent.GameEventRaised> stateListeners = new Dictionary<State, GameEvent.GameEventRaised>(); + + // ------------------------------------------------------------------------ + void OnEnable() { + StartCoroutine(ActivateStartingState()); + + // Start listening to the events that will change our state + foreach (var state in possibleStates) { + GameEvent.GameEventRaised listener = delegate() { ActivateState(state); }; + state.enterEvent.OnRaised += listener; + stateListeners.Add(state, listener); + } + } + + // ------------------------------------------------------------------------ + void OnDisable() { + if (currentState != null) { + DeactivateState(currentState); + } + + // Stop listening to the events that will change our state + foreach (var state in possibleStates) { + state.enterEvent.OnRaised -= stateListeners[state]; + } + stateListeners.Clear(); + } + + // ------------------------------------------------------------------------ + private IEnumerator ActivateStartingState() { + // Wait one frame to make sure all starting listeners have a chance to setup + yield return null; + ActivateState(startingState); + } + + // ------------------------------------------------------------------------ + private void ActivateState(State state) { + // Can't transition into a state we're already in + if (currentState != state) { + if (currentState != null) { + DeactivateState(currentState); + } + + currentState = state; + state.EnterState(); + } + } + + // ------------------------------------------------------------------------ + private void DeactivateState(State state) { + if (state == currentState) { + currentState = null; + } + state.ExitState(); + } + } +} diff --git a/State Manager/StateManager.cs.meta b/State Manager/StateManager.cs.meta new file mode 100644 index 0000000..1d78084 --- /dev/null +++ b/State Manager/StateManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a55df0166f51f7941954952e3c47dfa0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/package.json b/package.json index 8f386ad..75c1eb8 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "com.futuretech.shared", "displayName": "FutureTech Shared", "description": "Contains shared items such as the Scriptable Variables.", - "version": "0.1.23", + "version": "0.1.24", "unity": "2019.2", "license": "MIT", "repository": { -- GitLab