unity之通用FSM有限状态机(一)

什么是有限状态机:

有限状态机是一种用来进行对象行为建模的工具,作用是描述对象在它的生命周期内所经历的状态序列,以及如何响应来自外界的各种事件。简单理解就是:状态满足条件下的一种处理机制。

有限状态机,任意时刻都处于有限状态集合中的某一状态。当获得一个输入字符时,将从当前状态转换到另一状态或仍保持当前状态。

每一个状态都有三种行为:进入、 执行、 离开。

 

对状态机有一个简单的了解之后,那么状态机在unity游戏开发中有哪些应用呢?

大多游戏都有以下流程:

这些流程,我们是不是可以理解为状态。

在AI 方面,游戏中的玩家行为大致有以下状态:

站立(待机)、跑、跳、普攻、技能1,技能2,技能3,受伤、控制(眩晕、禁锢)、死亡 等等

 

以上2种举例都可体现有限状态机在游戏中的应用。故设计通用的状态机就显得很有必要。而不是为每一个应用都写一个状态机。

 

废话不多说,直接上代码

状态机基类:都存在编号、当前状态 抽象到基类。

 1 public abstract class TestFsmBase
 2 {
 3     /// <summary>
 4     /// 状态机编号
 5     /// </summary>
 6     public int FsmId { get; private set; }
 7 
 8     /// <summary>
 9     /// 状态机当前的状态
10     /// </summary>
11     public sbyte CurrState;
12 
13 
14     public TestFsmBase(int fsmId)
15     {
16         FsmId = fsmId;
17     }
18 
19     /// <summary>
20     /// 关闭
21     /// </summary>
22     public abstract void ShutDown();
23 }

 

状态机状态:进入  执行 离开  最基本的三种行为。

 1 public class TestFsmState<T> where T : class
 2 {
 3     public TestFsm<T> CurrFsm;
 4 
 5     public virtual void OnEnter()
 6     {
 7     }
 8 
 9     public virtual void OnUpdate()
10     {
11     }
12 
13     public virtual void OnLeave()
14     {
15     }
16 
17     public virtual void OnDestroy()
18     {
19 
20     }
21 }

 

状态机:

1.状态机的拥有者

2.状态机都有哪些状态

3.切换状态

4.关闭状态机

 1 using System.Collections.Generic;
 2 
 3 public class TestFsm<T> : TestFsmBase where T : class
 4 {
 5     /// <summary>
 6     /// 状态机拥有者
 7     /// </summary>
 8     public T Owner { get; private set; }
 9 
10     public TestFsmState<T> m_CurrFsmState;
11 
12     public Dictionary<sbyte, TestFsmState<T>> m_StateDic;
13 
14 
15     public TestFsm(int fsmId, T owner, TestFsmState<T>[] status) : base(fsmId)
16     {
17         Owner = owner;
18         m_StateDic = new Dictionary<sbyte, TestFsmState<T>>();
19         for (int i = 0; i < status.Length; i++)
20         {
21             m_StateDic[(sbyte)i] = status[i];
22             status[i].CurrFsm = this;//状态的状态机就是Fsm本身
23         }
24         CurrState = -1;
25     }
26 
27     /// <summary>
28     /// 获取状态
29     /// </summary>
30     /// <returns></returns>
31     public TestFsmState<T> GetState(sbyte stateType)
32     {
33         m_StateDic.TryGetValue(stateType, out TestFsmState<T> fsmState);
34         return fsmState;
35     }
36 
37     /// <summary>
38     /// 切换状态
39     /// </summary>
40     /// <param name="newState"></param>
41     public void ChangeState(sbyte newState)
42     {
43         //上一个状态离开 新状态进入
44         if (newState == CurrStateType) return;
45         if (m_CurrFsmState != null)
46         {
47             m_CurrFsmState.OnLeave();
48         }
49         if (m_StateDic.TryGetValue(newState, out TestFsmState<T> newFsmState))
50         {
51             CurrState = newState;
52             m_CurrFsmState = newFsmState;
53             m_CurrFsmState.OnEnter();
54         }
55     }
56 
57     public void OnUpdate()
58     {
59         if (m_CurrFsmState != null)
60         {
61             m_CurrFsmState.OnUpdate();
62         }
63     }
64 
65     /// <summary>
66     /// 关闭状态机
67     /// </summary>
68     public override void ShutDown()
69     {
70         if (m_CurrFsmState != null)
71         {
72             m_CurrFsmState.OnLeave();
73         }
74         var enumerator = m_StateDic.GetEnumerator();
75         while (enumerator.MoveNext())
76         {
77             enumerator.Current.Value.OnDestroy();
78         }
79         m_StateDic.Clear();
80     }
81 }

 

状态机管理器:.创建 、存在、 销毁

 1 using System;
 2 using System.Collections.Generic;
 3 
 4 /// <summary>
 5 /// 状态机管理器
 6 /// </summary>
 7 public class TestFsmManager : IDisposable
 8 {
 9     private int m_tempFsmId = 1;
10     private readonly Dictionary<int, TestFsmBase> fmsDic;
11 
12     public TestFsmManager()
13     {
14         fmsDic = new Dictionary<int, TestFsmBase>();
15     }
16 
17     /// <summary>
18     /// 创建
19     /// </summary>
20     /// <typeparam name="T"></typeparam>
21     /// <param name="own"></param>
22     /// <param name="status"></param>
23     /// <returns></returns>
24     public TestFsm<T> CreateFsm<T>(T owner, TestFsmState<T>[] status) where T : class
25     {
26         TestFsm<T> fsm = new TestFsm<T>(m_tempFsmId++, owner, status);
27         fmsDic[m_tempFsmId] = fsm;
28         return fsm;
29     }
30 
31     /// <summary>
32     /// 是否存在
33     /// </summary>
34     /// <param name="fsmId"></param>
35     /// <returns></returns>
36     public bool HasFsm(int fsmId)
37     {
38         return fmsDic.ContainsKey(fsmId);
39     }
40 
41     /// <summary>
42     /// 销毁
43     /// </summary>
44     /// <param name="fsmId"></param>
45     public void DestroyFsm(int fsmId)
46     {
47         if (fmsDic.TryGetValue(fsmId, out TestFsmBase fsmBase))
48         {
49             fsmBase.ShutDown();
50             fmsDic.Remove(fsmId);
51         }
52     }
53 
54     public void Dispose()
55     {
56         var enumerator = fmsDic.GetEnumerator();
57         while (enumerator.MoveNext())
58         {
59             enumerator.Current.Value.ShutDown();
60         }
61         fmsDic.Clear();
62     }
63 }

 

接下来,讲解下状态机在流程应用方面是如何使用的。

unity之通用FSM有限状态机 —>流程管理的使用(二)

posted @ 2022-05-03 23:06  赵不灰  阅读(936)  评论(0编辑  收藏  举报