零、大致逻辑
1.初始化 Start
组件->状态->状态内部初始化->进入初始状态
2.运行时 Update
遍历状态的所有条件->
不满足所有条件对象->执行当前状态运行时逻辑->进行一次玩家搜索
满足某一个条件对象->执行当前状态退出逻辑->执行状态改变->执行新状态进入逻辑->执行新状态运行时逻辑->进行一次玩家搜索
3.销毁时 OnDestroy
清空所有状态内部数据->清空状态机数据->清空所有状态
一、状态机配置文件和它的工厂
状态机需要知道当前对象会有哪些状态,且状态需要知道有哪些条件
并以Dictionary<状态, Dictionary<条件, 目标状态>>存到状态机内部
状态机填一个文件名,数据以txt方式存在于StreamAsset文件夹下
使用反射,将这一个个字符串变成状态类和条件类
那么,该如何去拿到这些字符串呢
我们使用一个工厂,状态机传字符串给工厂
工厂看看自己的缓存中有没有,有就给你,没有就new
下方的类就和一个字符串相匹配Dictionary<string, FSMConfigFlie>
状态机配置文件初始化
public class FSMConfigFlie
{
public Dictionary<string, Dictionary<string, string>> Map;
private string current = "";
//这是供工厂使用的文件读取方法
public FSMConfigFlie(string fileName)
{
Map = new Dictionary<string, Dictionary<string, string>>();
BuildMap(ConfigFile.GetConfigFile(fileName), MyBuildMap);
}
//这是其他地方写的享元函数,但由于篇幅太大,就直接提过来了
private void BuildMap(string paths,Action<string> handler)
{
using (StringReader reader = new StringReader(paths))
{
string line;
while ((line = reader.ReadLine()) != null)
{
handler(line);
}
}
//StringReader是个数据流,在使用完毕后要关闭,倘若中途出错,就不会关了
//但是用using括起来,那么只要它运行完毕, 肯定关了。
}
//详细解析
private void MyBuildMap(string line)
{
if (line.StartsWith("["))
{
current = line.Substring(1, line.Length - 2);
Map.Add(current, new Dictionary<string, string>());
}
else if (line.Contains(">"))
{
string[] keyValue = line.Split('>');
Map[current].Add(keyValue[0], keyValue[1]);
}
}
}
配置文件Map缓存
public class FSMConfigFlieFactory
{
//缓存
public static Dictionary<string, FSMConfigFlie> OMap;
//静态变量
static FSMConfigFlieFactory()
{
OMap = new Dictionary<string, FSMConfigFlie>();
}
//供外部使用的状态数据获取方法
public static Dictionary<string, Dictionary<string, string>> GetMap(string file)
{
if (!OMap.ContainsKey(file))
{
OMap.Add(file, new FSMConfigFlie(file));
}
return OMap[file].Map;
}
}
此时,我们就获得了
Dictionary<状态, Dictionary<条件, 目标状态>>
二、状态抽象类
然后,就是状态类,拿到Dictionary<状态, Dictionary<条件, 目标状态>>中的Value