TEngine--Fsm模块

Fsm模块

Fsm模块(Fsm又叫有限状态机)可以用于角色行为控制、游戏ai、流程控制等情况。通俗来讲就是一个可以在不同状态之间切换,并且同一时间只能有一种状态的设计。

有限 指的就是同一时间只能有一种状态
状态机 也顾名思义有多个状态且能根据逻辑切换

网上有很多类似的介绍,就不过多叙述了,可以自行查阅相关资料。

Fsm模块类图分析

Fsm类图
上面的类图虽然看起来很多,但是我们只需先按照之前学过的整体框架分析,就可以知道这四个类里,只有FsmModule是继承了mono的。但是FsmModule类里并没有发现Update是怎么回事?>_<

别急,其实在类里的Awake方法实现了Module类里的注册,然后root模块里的Update方法实现了ModuleImpSystem注册模块管理的轮询,最终一层一层的下放到Fsm、FsmManger和FsmState类里了。

1.FsmModule和FsmManager

正如之前整体框架分析所说的,Module类主要负责查看和使用API,ModuleImp类主要负责逻辑。所有我们在使用Fsm管理的时候最好用FsmModule方法来创建、销毁、获取Fsm状态机等操作。

2.Fsm类

Fsm类主要是管理状态类的,包括开始状态、检查状态、切换状态、读取所有状态以及在状态之间传递数据。
这些方法都可以在FsmState类的方法里,通过参数使用。

1
2
3
4
protected internal virtual void OnInit(IFsm<T> fsm)
{
fsm.SetData("testfsm","testdata");
}

3.FsmState类

和流程类的图例一样,只不过这里会再多说一下OnInit()和Destory()。一个是状态初始化时调用、状态销毁时调用。也就是说切换状态只调用OnEnter()、OnUpdate()、OnLeave()。
一个FsmState状态图例

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
using System;

namespace TEngine
{
/// <summary>
/// 有限状态机状态基类。
/// </summary>
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
public abstract class FsmState<T> where T : class
{
/// <summary>
/// 初始化有限状态机状态基类的新实例。
/// </summary>
public FsmState()
{
}

/// <summary>
/// 有限状态机状态初始化时调用。
/// </summary>
/// <param name="fsm">有限状态机引用。</param>
protected internal virtual void OnInit(IFsm<T> fsm)
{

}

/// <summary>
/// 有限状态机状态进入时调用。
/// </summary>
/// <param name="fsm">有限状态机引用。</param>
protected internal virtual void OnEnter(IFsm<T> fsm)
{
}

/// <summary>
/// 有限状态机状态轮询时调用。
/// </summary>
/// <param name="fsm">有限状态机引用。</param>
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
protected internal virtual void OnUpdate(IFsm<T> fsm, float elapseSeconds, float realElapseSeconds)
{
}

/// <summary>
/// 有限状态机状态离开时调用。
/// </summary>
/// <param name="fsm">有限状态机引用。</param>
/// <param name="isShutdown">是否是关闭有限状态机时触发。</param>
protected internal virtual void OnLeave(IFsm<T> fsm, bool isShutdown)
{
}

/// <summary>
/// 有限状态机状态销毁时调用。
/// </summary>
/// <param name="fsm">有限状态机引用。</param>
protected internal virtual void OnDestroy(IFsm<T> fsm)
{
}

/// <summary>
/// 切换当前有限状态机状态。
/// </summary>
/// <typeparam name="TState">要切换到的有限状态机状态类型。</typeparam>
/// <param name="fsm">有限状态机引用。</param>
protected void ChangeState<TState>(IFsm<T> fsm) where TState : FsmState<T>
{
Fsm<T> fsmImplement = (Fsm<T>)fsm;
if (fsmImplement == null)
{
throw new GameFrameworkException("FSM is invalid.");
}

fsmImplement.ChangeState<TState>();
}

/// <summary>
/// 切换当前有限状态机状态。
/// </summary>
/// <param name="fsm">有限状态机引用。</param>
/// <param name="stateType">要切换到的有限状态机状态类型。</param>
protected void ChangeState(IFsm<T> fsm, Type stateType)
{
Fsm<T> fsmImplement = (Fsm<T>)fsm;
if (fsmImplement == null)
{
throw new GameFrameworkException("FSM is invalid.");
}

if (stateType == null)
{
throw new GameFrameworkException("State type is invalid.");
}

if (!typeof(FsmState<T>).IsAssignableFrom(stateType))
{
throw new GameFrameworkException(Utility.Text.Format("State type '{0}' is invalid.", stateType.FullName));
}

fsmImplement.ChangeState(stateType);
}
}
}


TEngine--Fsm模块
https://www.liu2dream.fun/post/TEngine--Fsm模块/
作者
刘老师 MrLiu
发布于
2024年6月2日
许可协议