零、大致邏輯
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