出处http://jxwgame.blog.51cto.com/943299/1608980
1
2
3
4
5
6
7
8
|
using UnityEngine;
using System.Collections;
public interface IState {
void OnEnter( string prevState);
void OnExit( string nextState);
void OnUpdate();
}
|
1
2
3
4
5
|
public
delegate
void
EnterState(
string
stateName);
public
delegate
void
PushState(
string
stateName,
string
lastStateName);
public
delegate
void
PopState();
|
1
2
3
|
protected
Dictionary<
string
, FSState> mStates;
protected
Stack<FSState> mStateStack;
|
1
2
3
4
5
6
7
8
9
|
public
void
Register(
string
stateName, IState stateObject) {
if
(mStates.Count == 0)
mEntryPoint = stateName;
mStates.Add(stateName,
new
FSState(stateObject,
this
, stateName, Enter, Push, Pop));
}
|
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
|
public
void
Push(
string
newState) {
string
lastName =
null
;
if
(mStateStack.Count > 1) {
lastName = mStateStack.Peek().StateName;
}
Push(newState, lastName);
}
protected
void
Push(
string
stateName,
string
lastStateName) {
mStateStack.Push(mStates[stateName]);
mStateStack.Peek().StateObject.OnEnter(lastStateName);
}
public
void
Pop() {
Pop(
null
);
}
protected
string
Pop(
string
newName) {
FSState lastState = mStateStack.Peek();
string
newState =
null
;
if
(newName ==
null
&& mStateStack.Count > 1) {
int
index = 0;
foreach
(FSState item
in
mStateStack) {
if
(index++ == mStateStack.Count - 2) {
newState = item.StateName;
}
}
}
else
{
newState = newName;
}
string
lastStateName =
null
;
if
(lastState !=
null
) {
lastStateName = lastState.StateName;
lastState.StateObject.OnExit(newState);
}
mStateStack.Pop();
return
lastStateName;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public
void
Trigger(
string
eventName) {
CurrentState.Trigger(eventName);
}
public
void
Trigger(
string
eventName,
object
param1) {
CurrentState.Trigger(eventName, param1);
}
public
void
Trigger(
string
eventName,
object
param1,
object
param2) {
CurrentState.Trigger(eventName, param1, param2);
}
public
void
Trigger(
string
eventName,
object
param1,
object
param2,
object
param3) {
CurrentState.Trigger(eventName, param1, param2, param3);
}
|
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
|
using
UnityEngine;
using
System.Collections;
using
System.Collections.Generic;
public
class
FiniteStateMachine {
public
delegate
void
EnterState(
string
stateName);
public
delegate
void
PushState(
string
stateName,
string
lastStateName);
public
delegate
void
PopState();
protected
Dictionary<
string
, FSState> mStates;
protected
string
mEntryPoint;
protected
Stack<FSState> mStateStack;
public
FiniteStateMachine() {
mStates =
new
Dictionary<
string
, FSState>();
mStateStack =
new
Stack<FSState>();
mEntryPoint =
null
;
}
public
void
Update() {
if
(CurrentState ==
null
) {
mStateStack.Push(mStates[mEntryPoint]);
CurrentState.StateObject.OnEnter(
null
);
}
CurrentState.StateObject.OnUpdate();
}
public
void
Register(
string
stateName, IState stateObject) {
if
(mStates.Count == 0)
mEntryPoint = stateName;
mStates.Add(stateName,
new
FSState(stateObject,
this
, stateName, Enter, Push, Pop));
}
public
FSState State(
string
stateName) {
return
mStates[stateName];
}
public
void
EntryPoint(
string
startName) {
mEntryPoint = startName;
}
public
FSState CurrentState {
get
{
if
(mStateStack.Count == 0)
return
null
;
return
mStateStack.Peek();
}
}
public
void
Enter(
string
stateName) {
Push(stateName, Pop(stateName));
}
public
void
Push(
string
newState) {
string
lastName =
null
;
if
(mStateStack.Count > 1) {
lastName = mStateStack.Peek().StateName;
}
Push(newState, lastName);
}
protected
void
Push(
string
stateName,
string
lastStateName) {
mStateStack.Push(mStates[stateName]);
mStateStack.Peek().StateObject.OnEnter(lastStateName);
}
public
void
Pop() {
Pop(
null
);
}
protected
string
Pop(
string
newName) {
FSState lastState = mStateStack.Peek();
string
newState =
null
;
if
(newName ==
null
&& mStateStack.Count > 1) {
int
index = 0;
foreach
(FSState item
in
mStateStack) {
if
(index++ == mStateStack.Count - 2) {
newState = item.StateName;
}
}
}
else
{
newState = newName;
}
string
lastStateName =
null
;
if
(lastState !=
null
) {
lastStateName = lastState.StateName;
lastState.StateObject.OnExit(newState);
}
mStateStack.Pop();
return
lastStateName;
}
public
void
Trigger(
string
eventName) {
CurrentState.Trigger(eventName);
}
public
void
Trigger(
string
eventName,
object
param1) {
CurrentState.Trigger(eventName, param1);
}
public
void
Trigger(
string
eventName,
object
param1,
object
param2) {
CurrentState.Trigger(eventName, param1, param2);
}
public
void
Trigger(
string
eventName,
object
param1,
object
param2,
object
param3) {
CurrentState.Trigger(eventName, param1, param2, param3);
}
}
|
1
2
3
|
protected
FiniteStateMachine.EnterState mEnterDelegate;
protected
FiniteStateMachine.PushState mPushDelegate;
protected
FiniteStateMachine.PopState mPopDelegate;
|
1
2
3
4
5
6
7
8
9
10
|
public
FSState(IState obj, FiniteStateMachine owner,
string
name, FiniteStateMachine.EnterState e, FiniteStateMachine.PushState pu, FiniteStateMachine.PopState po) {
mStateObject = obj;
mStateName = name;
mOwner = owner;
mEnterDelegate = e;
mPushDelegate = pu;
mPopDelegate = po;
mTranslationEvents =
new
Dictionary<
string
, FSEvent>();
}
|
1
2
3
4
5
6
|
public
FSEvent On(
string
eventName) {
FSEvent newEvent =
new
FSEvent(eventName,
null
,
this
, mOwner, mEnterDelegate, mPushDelegate, mPopDelegate);
mTranslationEvents.Add(eventName, newEvent);
return
newEvent;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public
void
Trigger(
string
name) {
mTranslationEvents[name].Execute(
null
,
null
,
null
);
}
public
void
Trigger(
string
eventName,
object
param1) {
mTranslationEvents[eventName].Execute(param1,
null
,
null
);
}
public
void
Trigger(
string
eventName,
object
param1,
object
param2) {
mTranslationEvents[eventName].Execute(param1, param2,
null
);
}
public
void
Trigger(
string
eventName,
object
param1,
object
param2,
object
param3) {
mTranslationEvents[eventName].Execute(param1, param2, param3);
}
|
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
|
using
System;
using
System.Collections;
using
System.Collections.Generic;
public
class
FSState {
protected
FiniteStateMachine.EnterState mEnterDelegate;
protected
FiniteStateMachine.PushState mPushDelegate;
protected
FiniteStateMachine.PopState mPopDelegate;
protected
IState mStateObject;
protected
string
mStateName;
protected
FiniteStateMachine mOwner;
protected
Dictionary<
string
, FSEvent> mTranslationEvents;
public
FSState(IState obj, FiniteStateMachine owner,
string
name, FiniteStateMachine.EnterState e, FiniteStateMachine.PushState pu, FiniteStateMachine.PopState po) {
mStateObject = obj;
mStateName = name;
mOwner = owner;
mEnterDelegate = e;
mPushDelegate = pu;
mPopDelegate = po;
mTranslationEvents =
new
Dictionary<
string
, FSEvent>();
}
public
IState StateObject {
get
{
return
mStateObject;
}
}
public
string
StateName {
get
{
return
mStateName;
}
}
public
FSEvent On(
string
eventName) {
FSEvent newEvent =
new
FSEvent(eventName,
null
,
this
, mOwner, mEnterDelegate, mPushDelegate, mPopDelegate);
mTranslationEvents.Add(eventName, newEvent);
return
newEvent;
}
public
void
Trigger(
string
name) {
mTranslationEvents[name].Execute(
null
,
null
,
null
);
}
public
void
Trigger(
string
eventName,
object
param1) {
mTranslationEvents[eventName].Execute(param1,
null
,
null
);
}
public
void
Trigger(
string
eventName,
object
param1,
object
param2) {
mTranslationEvents[eventName].Execute(param1, param2,
null
);
}
public
void
Trigger(
string
eventName,
object
param1,
object
param2,
object
param3) {
mTranslationEvents[eventName].Execute(param1, param2, param3);
}
public
FSState On<T>(
string
eventName, Func<T,
bool
> action) {
FSEvent newEvent =
new
FSEvent(eventName,
null
,
this
, mOwner, mEnterDelegate, mPushDelegate, mPopDelegate);
newEvent.mAction =
delegate
(
object
o1,
object
o2,
object
o3) {
T param1;
try
{ param1 = (T)o1; }
catch
{ param1 =
default
(T); }
action(param1);
return
true
;
};
mTranslationEvents.Add(eventName, newEvent);
return
this
;
}
public
FSState On<T>(
string
eventName, Action<T> action) {
FSEvent newEvent =
new
FSEvent(eventName,
null
,
this
, mOwner, mEnterDelegate, mPushDelegate, mPopDelegate);
newEvent.mAction =
delegate
(
object
o1,
object
o2,
object
o3) {
T param1;
try
{ param1 = (T)o1; }
catch
{ param1 =
default
(T); }
action(param1);
return
true
;
};
mTranslationEvents.Add(eventName, newEvent);
return
this
;
}
public
FSState On<T1, T2>(
string
eventName, Func<T1, T2,
bool
> action) {
FSEvent newEvent =
new
FSEvent(eventName,
null
,
this
, mOwner, mEnterDelegate, mPushDelegate, mPopDelegate);
newEvent.mAction =
delegate
(
object
o1,
object
o2,
object
o3) {
T1 param1;
T2 param2;
try
{ param1 = (T1)o1; }
catch
{ param1 =
default
(T1); }
try
{ param2 = (T2)o2; }
catch
{ param2 =
default
(T2); }
action(param1, param2);
return
true
;
};
mTranslationEvents.Add(eventName, newEvent);
return
this
;
}
public
FSState On<T1, T2>(
string
eventName, Action<T1, T2> action) {
FSEvent newEvent =
new
FSEvent(eventName,
null
,
this
, mOwner, mEnterDelegate, mPushDelegate, mPopDelegate);
newEvent.mAction =
delegate
(
object
o1,
object
o2,
object
o3) {
T1 param1;
T2 param2;
try
{ param1 = (T1)o1; }
catch
{ param1 =
default
(T1); }
try
{ param2 = (T2)o2; }
catch
{ param2 =
default
(T2); }
action(param1, param2);
return
true
;
};
mTranslationEvents.Add(eventName, newEvent);
return
this
;
}
public
FSState On<T1, T2, T3>(
string
eventName, Func<T1, T2, T3,
bool
> action) {
FSEvent newEvent =
new
FSEvent(eventName,
null
,
this
, mOwner, mEnterDelegate, mPushDelegate, mPopDelegate);
newEvent.mAction =
delegate
(
object
o1,
object
o2,
object
o3) {
T1 param1;
T2 param2;
T3 param3;
try
{ param1 = (T1)o1; }
catch
{ param1 =
default
(T1); }
try
{ param2 = (T2)o2; }
catch
{ param2 =
default
(T2); }
try
{ param3 = (T3)o3; }
catch
{ param3 =
default
(T3); }
action(param1, param2, param3);
return
true
;
};
mTranslationEvents.Add(eventName, newEvent);
return
this
;
}
public
FSState On<T1, T2, T3>(
string
eventName, Action<T1, T2, T3> action) {
FSEvent newEvent =
new
FSEvent(eventName,
null
,
this
, mOwner, mEnterDelegate, mPushDelegate, mPopDelegate);
newEvent.mAction =
delegate
(
object
o1,
object
o2,
object
o3) {
T1 param1;
T2 param2;
T3 param3;
try
{ param1 = (T1)o1; }
catch
{ param1 =
default
(T1); }
try
{ param2 = (T2)o2; }
catch
{ param2 =
default
(T2); }
try
{ param3 = (T3)o3; }
catch
{ param3 =
default
(T3); }
action(param1, param2, param3);
return
true
;
};
mTranslationEvents.Add(eventName, newEvent);
return
this
;
}
}
|
1
2
3
|
protected
FiniteStateMachine.EnterState mEnterDelegate;
protected
FiniteStateMachine.PushState mPushDelegate;
protected
FiniteStateMachine.PopState mPopDelegate;
|
1
|
public
Func<
object
,
object
,
object
,
bool
> mAction =
null
;
|
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
|
public
FSState Enter(
string
stateName) {
mTargetState = stateName;
eType = EventType.ENTER;
return
mStateOwner;
}
public
FSState Push(
string
stateName) {
mTargetState = stateName;
eType = EventType.PUSH;
return
mStateOwner;
}
public
void
Pop() {
eType = EventType.POP;
}
public
void
Execute(
object
o1,
object
o2,
object
o3) {
if
(eType == EventType.POP) {
mPopDelegate();
}
else
if
(eType == EventType.PUSH) {
mPushDelegate(mTargetState, mOwner.CurrentState.StateName);
}
else
if
(eType == EventType.ENTER) {
mEnterDelegate(mTargetState);
}
else
if
(mAction !=
null
) {
mAction(o1, o2, o3);
}
}
|
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
|
using
System;
public
class
FSEvent {
protected
FiniteStateMachine.EnterState mEnterDelegate;
protected
FiniteStateMachine.PushState mPushDelegate;
protected
FiniteStateMachine.PopState mPopDelegate;
protected
enum
EventType { NONE, ENTER, PUSH, POP };
protected
string
mEventName;
protected
FSState mStateOwner;
protected
string
mTargetState;
protected
FiniteStateMachine mOwner;
protected
EventType eType;
public
Func<
object
,
object
,
object
,
bool
> mAction =
null
;
public
FSEvent(
string
name,
string
target, FSState state, FiniteStateMachine owner, FiniteStateMachine.EnterState e, FiniteStateMachine.PushState pu, FiniteStateMachine.PopState po) {
mStateOwner = state;
mEventName = name;
mTargetState = target;
mOwner = owner;
eType = EventType.NONE;
mEnterDelegate = e;
mPushDelegate = pu;
mPopDelegate = po;
}
public
FSState Enter(
string
stateName) {
mTargetState = stateName;
eType = EventType.ENTER;
return
mStateOwner;
}
public
FSState Push(
string
stateName) {
mTargetState = stateName;
eType = EventType.PUSH;
return
mStateOwner;
}
public
void
Pop() {
eType = EventType.POP;
}
public
void
Execute(
object
o1,
object
o2,
object
o3) {
if
(eType == EventType.POP) {
mPopDelegate();
}
else
if
(eType == EventType.PUSH) {
mPushDelegate(mTargetState, mOwner.CurrentState.StateName);
}
else
if
(eType == EventType.ENTER) {
mEnterDelegate(mTargetState);
}
else
if
(mAction !=
null
) {
mAction(o1, o2, o3);
}
}
}
|