# 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();
}
}
```