-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathStateBase.cs
161 lines (138 loc) · 5.34 KB
/
StateBase.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
namespace Buffer.HFSM
{
/// <summary>
/// Base class for all states.
/// </summary>
public abstract class StateBase
{
protected bool isRootState;
protected StateBase currentSuperState;
protected StateBase currentSubState;
public bool IsRootState { get { return isRootState; } }
public StateBase CurrentSuperState { get { return currentSuperState; } }
public StateBase CurrentSubState { get { return currentSubState; } set { currentSubState = value; } }
/// <summary> Sets the basic values of the state. </summary>
/// <param name="machine"> State machine owning this state. </param>
public virtual void Setup(StateMachine machine)
{
Initialize();
}
/// <summary>
/// Sets the super state of this state.
/// </summary>
/// <param name="superState"></param>
public virtual void SetSuperState(StateBase superState)
{
currentSuperState = superState;
}
/// <summary> Initialization of the state - a method invoked only once, when the state is created. </summary>
public virtual void Initialize() { }
/// <summary> Defines if the state can be entered. </summary>
public virtual bool CanEnterState()
{
return true;
}
/// <summary> Invoked when the machine enters this state. </summary>
public virtual void OnEnterState() { }
/// <summary> Invoked in Update of the machine, if this is its current state. </summary>
public virtual void Update(float dt)
{
if (currentSubState != null)
currentSubState.Update(dt);
}
/// <summary> Invoked in FixedUpdate of the machine, if this is its current state. </summary>
public virtual void FixedUpdate(float fdt)
{
if (currentSubState != null)
currentSubState.FixedUpdate(fdt);
}
/// <summary> Invoked in LateUpdate of the machine, if this is its current state. </summary>
public virtual void LateUpdate(float dt)
{
if (currentSubState != null)
currentSubState.LateUpdate(dt);
}
/// <summary>
/// Invoked in LateFixedUpdate of the machine, if this is its current state.
/// E.g called AFTER Physics internal update.
/// </summary>
/// <param name="fdt"></param>
public virtual void LateFixedUpdate(float fdt)
{
if (currentSubState != null)
currentSubState.LateFixedUpdate(fdt);
}
/// <summary> Checks if the machine should switch to another state. </summary>
public virtual void CheckIfShouldSwitchState() { }
public virtual bool CanExit()
{
return true;
}
/// <summary> Invoked just before the machine exits this state. </summary>
public virtual void OnExitState()
{
currentSubState?.OnExitState();
}
public virtual void OnDrawGizmos() { }
public virtual void OnDrawGizmosSelected() { }
}
/// <summary> One of the states the StateMachine can use. </summary>
/// <typeparam name="T">StateMachine that owns this State.</typeparam>
public abstract class State<T> : StateBase where T : StateMachine
{
protected T machine;
public override void Setup(StateMachine machine)
{
this.machine = machine as T;
base.Setup(machine);
if (!isRootState)
currentSuperState = machine.CurrentState;
}
/// <summary> Tries to set current state. </summary>
protected void TrySetState<T1>() where T1 : StateBase, new()
{
machine.TrySetState<T1>();
}
/// <summary>
/// Tries to set current substate.
/// </summary>
/// <typeparam name="T1"></typeparam>
protected void TrySetSubState<T1>() where T1 : StateBase, new()
{
T1 state = machine.factory.GetState<T1>();
if (state == currentSubState) return;
if (state.CanEnterState()) SetSubState(state);
}
/// <summary>
/// Can set the substate of a super state from a substate
/// </summary>
/// <typeparam name="T1"></typeparam>
protected void TrySetSubState<T1>(StateBase state) where T1 : StateBase, new()
{
state = machine.factory.GetState<T1>();
if (state == currentSubState) return;
if (state.CanEnterState()) SetSubState(state);
}
/// <summary>
/// Sets the substate
/// </summary>
/// <param name="newState"></param>
protected void SetSubState(StateBase newState)
{
// Check if a current substate exists and if it can be exited.
if (currentSubState != null && !currentSubState.CanExit())
{
return;
}
// Exit the current substate, if it exists.
currentSubState?.OnExitState();
// Set and enter the new substate.
currentSubState = newState;
if (currentSubState != null)
{
currentSubState.OnEnterState();
currentSubState.SetSuperState(this);
}
}
}
}