-
Notifications
You must be signed in to change notification settings - Fork 1
/
State.cs
91 lines (77 loc) · 3.19 KB
/
State.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
using UnityEngine;
/// <summary>
/// A basic State class implementation that uses <see cref="Action">Actions</see> and <see cref="StateDecisionTree">State Decision Trees</see>.
/// </summary>
[CreateAssetMenu(menuName = "Game/State Machine/State")]
public class State : ScriptableObject
{
//A reference to the state machine that currently holds this state (which means a State can only be used on one StateMachine at a time)
private StateMachine m_StateMachine;
[SerializeField, Tooltip("A list of all actions associated with this state")] private Action[] m_Actions;
[SerializeField, Tooltip("A list of all state decisions and their associated states")] private StateDecisionTree[] m_Decisions;
/// <summary>
/// Called whenever this state is added to a state machine
/// </summary>
/// <param name="stateMachine">The state machine that contains this state</param>
public void OnAdded(StateMachine stateMachine)
{
m_StateMachine = stateMachine;
//Add all the actions to this statte
for (int i = 0; i < m_Actions.Length; i++)
m_Actions[i].OnAdded(stateMachine, this);
//Add all the decisions to this state
for (int i = 0; i < m_Decisions.Length; i++)
{
StateDecisionTree decisionTree = m_Decisions[i];
for (int j = 0; j < decisionTree.m_Decisions.Length; j++)
decisionTree.m_Decisions[i].OnAdded(stateMachine, this);
}
}
/// <summary>
/// Called once every frame this state is active
/// </summary>
public void OnUpdate()
{
//Update all the actions on this state
for (int i = 0; i < m_Actions.Length; i++)
m_Actions[i].OnUpdate();
//Go through every state decision tree
for (int i = 0; i < m_Decisions.Length; i++)
{
//Decide what the new state should be
StateDecisionTree decisionTree = m_Decisions[i];
bool decision = true;
for (int j = 0; j < decisionTree.m_Decisions.Length; j++)
{
if (!decisionTree.m_Decisions[j].Decide())
{
decision = false;
break;
}
}
State newState = decision ? m_Decisions[i].m_TrueState : m_Decisions[i].m_FalseState;
//If it is a valid state, change to that state and exit this loop
if (newState != null)
{
m_StateMachine.ChangeState(newState);
break;
}
}
}
/// <summary>
/// Called whenever the state machine no longer has a reference to this state
/// </summary>
public void OnRemoved()
{
//Remove all the actions
for (int i = 0; i < m_Actions.Length; i++)
m_Actions[i].OnRemoved();
//Remove all the state decision trees
for (int i = 0; i < m_Decisions.Length; i++)
{
StateDecisionTree decisionTree = m_Decisions[i];
for (int j = 0; j < decisionTree.m_Decisions.Length; j++)
decisionTree.m_Decisions[i].OnRemoved();
}
}
}