# Generic States & Extensions ###### tags: `state machine` We have implemented some generic states that are reusable and we can add them very quick through StateMachineManager’s extensions. * ActionState * DelayState * NotificationState * WaitForKey01State * IndieTaskState ## Action State ```csharp public static void AddActionState(this StateMachineManager smm, Enum state, Action onEnter = null, Action onUpdate = null, Action onExit = null) ``` With Action State we can add a generic state passing the onEnter, onUpdate and onExit methods as a reference. These methods can be null. ### Example In this example, the state machine has one state `CountFrames` which is counting the frames while the state is alive and prints the frames to the console on exit the state, pressing the space key. ```csharp public class Example : MonoBehaviour { private StateMachineManager m_SMManager; private int m_FrameCount; private enum States { CountFrames } // enum for States private enum Params { SpacePressed } // enum for Parameters private void Start() { // create state machine m_SMManager = StateMachineManager.Create(this.gameObject); // add generic action state m_SMManager.AddActionState( States.CountFrames, //state enum onEnter: () => m_FrameCount = 0, onUpdate: () => m_FrameCount++, onExit: () => Debug.LogFormat("The state was alive for {0} frames", m_FrameCount) ); // register trigger param m_SMManager.RegisterTriggerParam(Params.SpacePressed); // add exit transition from CountFrames state when Space key pressed is fired m_SMManager.AddExitTransition(States.CountFrames, new TriggerCondition(Params.SpacePressed)); // start state machine m_SMManager.StartStateMachine(); } private void Update() { // fire SpacePressed trigger param on Space key pressed if (Input.GetKeyDown(KeyCode.Space)) m_SMManager.SetTriggerParam((int)Params.SpacePressed); } } ``` ## Delay State ```csharp public static void AddDelayState(this StateMachineManager smm, Enum state, float delay, Enum nextState = null) ``` With Delay State, we can implement a delay for specific time effect before we progress to the next state. If the next state is null, we exit the state machine. The paramId must be a unique enum in the state machine context referring to the specified delay. ### Example In this example, we define a Delay state which will wait for 5 seconds and the will exit the state machine. ```csharp public class GenericDelayStateExample : MonoBehaviour { private StateMachineManager m_SMManager; private enum States { Delay } private void Start() { // create state machine m_SMManager = StateMachineManager.Create(this.gameObject); // add generic delay state m_SMManager.AddDelayState(States.Delay, 5f); // start state machine m_SMManager.StartStateMachine(); } } ``` ## Notification State ```csharp public static void AddNotificationState (this StateMachineManager smm, Enum state, UI.ContentNotificationData notification, Action onEnter = null) ``` With Notification State we create a state in which we show the notification onEnter. Also we can add a onEnter action. ### Example In this example, we add 2 notification states. Each one shows a notification (`m_Note1`, `m_Note2`). We also define a SpacePressed trigger param to implement 2 transitions: Note01->Note02->EXIT. ```csharp public class GenericNotificationStateExample : MonoBehaviour { #pragma warning disable 649 [SerializeField] UI.ContentNotificationData m_Note1; [SerializeField] UI.ContentNotificationData m_Note2; #pragma warning restore 649 private StateMachineManager m_SMManager; private enum States { Note01, Note02 } private enum Params { SpacePressed } private void Start() { // create state machine m_SMManager = StateMachineManager.Create(this.gameObject); // add generic note states m_SMManager.AddNotificationState(States.Note01, m_Note1); m_SMManager.AddNotificationState(States.Note02, m_Note1); // register trigger parameter m_SMManager.RegisterTriggerParam(Params.SpacePressed); // add transitions m_SMManager.AddTransition(States.Note01, States.Note02, new TriggerCondition(Params.SpacePressed)); m_SMManager.AddExitTransition(States.Note02, new TriggerCondition(Params.SpacePressed)); // start state machine m_SMManager.StartStateMachine(); } private void Update() { // fire SpacePressed trigger param on Space key pressed if (Input.GetKeyDown(KeyCode.Space)) m_SMManager.SetTriggerParam((int)Params.SpacePressed); } } ``` ## Wait For Key 01 State ```csharp public static void AddWaitForKey01State(this StateMachineManager smm, Enum state, UI.ContentNotificationData notificationData, Enum nextState = null, Action onExit = null) ``` With Wait For Key 01 State we create a state in which we show the notification onEnter, wait until the user presses the 01 shortcut and then we go to the next state if is not null, otherwise we exit the state machine. Also, we can add a onExit action. The paramId must be a unique enum in the state machine context referring to the specified delay. ### Example In this example, we add a WaitForKey01State which shows the m_Note notification and waits for the 01 shortcut to be pressed in order to exit the state machine. ```csharp public class GenericWaitForKey01StateExample : MonoBehaviour { #pragma warning disable 649 [SerializeField] UI.ContentNotificationData m_Note; #pragma warning restore 649 private StateMachineManager m_SMManager; private enum States { WaitFor01 } private void Start() { // create state machine m_SMManager = StateMachineManager.Create(this.gameObject); // add generic wait for key 01 state m_SMManager.AddWaitForKey01State(States.WaitFor01, m_Note); // start state machine m_SMManager.StartStateMachine(); } } ``` ## Indie Task State ```csharp public static void AddIndieTaskState(this StateMachineManager smm, Enum state, IndieTaskStateMachineManager indieTask, UI.ContentNotificationData dialogueData = null, Enum nextState = null) ``` ### Example ```csharp public class GenericIndieTaskExample : MonoBehaviour { #pragma warning disable 649 [SerializeField] IndieTaskStateMachineManager m_IndieTask; [SerializeField] UI.ContentNotificationData m_Dialogue; #pragma warning restore 649 private StateMachineManager m_SMManager; private enum States { IndieTaskState } void Start() { // create state machine m_SMManager = StateMachineManager.Create(this.gameObject); // add generic note states m_SMManager.AddIndieTaskState(States.IndieTaskState, m_IndieTask, m_Dialogue); // start state machine m_SMManager.StartStateMachine(); } } ```