zoukankan      html  css  js  c++  java
  • Unity FSM状态机

    状态类:

      1 using System;
      2 using System.Collections;
      3 using System.Collections.Generic;
      4 using UnityEngine;
      5 
      6 public class State 
      7 {
      8     /// <summary>
      9     /// 存储状态能够转换的列表
     10     /// </summary>
     11     protected List<Type> list = new List<Type>();
     12 
     13     /// <summary>
     14     /// 添加可转换状态到列表中存储
     15     /// </summary>
     16     /// <typeparam name="T"></typeparam>
     17     public void AddTransition<T>() where T :State
     18     {
     19         if (list.Contains(typeof(T)))
     20         {
     21             Debug.LogError("转换状态:" + typeof(T) + "已经有了对应的状态");
     22             return;
     23         }
     24         list.Add(typeof(T));
     25     }
     26 
     27     /// <summary>
     28     /// 从列表中删除某个可转换的状态
     29     /// </summary>
     30     /// <typeparam name="T"></typeparam>
     31     public void DeleteTransition<T>() where T : State
     32     {
     33         if (list.Contains(typeof(T)) == false)
     34         {
     35             Debug.LogWarning("转换条件:" + typeof(T) + "没有存在在map字典内!");
     36             return;
     37         }
     38         list.Remove(typeof(T));
     39     }
     40 
     41     /// <summary>
     42     /// 判断某个类型是否可转换
     43     /// </summary>
     44     /// <param name="type"></param>
     45     /// <returns></returns>
     46     public bool IsTransition(Type type)
     47     {
     48         if (list.Contains(type))
     49         {
     50             return true;
     51         }
     52         return false;
     53     }
     54 
     55     /// <summary>
     56     /// 状态是否启用
     57     /// </summary>
     58     public bool isActive
     59     {
     60         get { return machine.IsCurrentState(GetType()); }
     61     }
     62 
     63     /// <summary>
     64     /// 获取控制当前状态的状态机
     65     /// </summary>
     66     public MachineBehaviour machine
     67     {
     68         get;
     69         internal set;
     70     }
     71 
     72     /// <summary>
     73     /// 状态初始化
     74     /// </summary>
     75     public virtual void Initialize()
     76     {
     77 
     78     }
     79     /// <summary>
     80     /// 进入状态时执行
     81     /// </summary>
     82     public virtual void Enter()
     83     {
     84 
     85     }
     86     /// <summary>
     87     /// 状态Update时执行
     88     /// </summary>
     89     public virtual void Execute()
     90     {
     91 
     92     }
     93     /// <summary>
     94     /// 退出状态时执行
     95     /// </summary>
     96     public virtual void Exit()
     97     {
     98 
     99     }
    100     /// <summary>
    101     /// 状态FixedUpdate时执行
    102     /// </summary>
    103     public virtual void FixedExecute()
    104     {
    105 
    106     }
    107     /// <summary>
    108     /// 状态LateUpdate时执行
    109     /// </summary>
    110     public virtual void LateExecute()
    111     {
    112 
    113     }
    114 
    115     public virtual void OnCollisionEnter(Collision collision)
    116     {
    117 
    118     }
    119     public virtual void OnCollisionExit(Collision collision)
    120     {
    121 
    122     }
    123     public virtual void OnCollisionStay(Collision collision)
    124     {
    125 
    126     }
    127     public virtual void OnTriggerEnter(Collider collider)
    128     {
    129 
    130     }
    131     public virtual void OnTriggerExit(Collider collider)
    132     {
    133 
    134     }
    135     public virtual void OnTriggerStay(Collider collider)
    136     {
    137 
    138     }
    139 }
    State

    状态机类:

      1 using System;
      2 using System.Collections;
      3 using System.Collections.Generic;
      4 using UnityEngine;
      5 
      6 public abstract class MachineBehaviour : MonoBehaviour
      7 {
      8     /// <summary>
      9     /// 状态机的当前状态
     10     /// </summary>
     11     protected State currentState { get; set; }
     12 
     13     /// <summary>
     14     /// 状态机存储的状态列表
     15     /// </summary>
     16     protected Dictionary<Type, State> states = new Dictionary<Type, State>();
     17 
     18     /// <summary>
     19     /// 对状态机添加一些状态
     20     /// </summary>
     21     public abstract void AddStates();
     22 
     23     /// <summary>
     24     /// 对状态机的初始化操作
     25     /// </summary>
     26     public virtual void Initialize()
     27     {
     28         AddStates();
     29 
     30         if (currentState == null)
     31         {
     32             throw new System.Exception("状态机:" + name + "的currentState没有设置,请通过SetCurrentState()函数设置!");
     33         }
     34 
     35         // 对状态机里的每个状态进行初始化
     36         foreach (KeyValuePair<Type, State> pair in states)
     37         {
     38             pair.Value.Initialize();
     39         }
     40 
     41         currentState.Enter();
     42     }
     43 
     44     /// <summary>
     45     /// 添加一个状态到状态机
     46     /// </summary>
     47     /// <typeparam name="T"></typeparam>
     48     public void AddState<T>() where T : State, new()
     49     {
     50         if (!ContainsState<T>())
     51         {
     52             State item = new T();
     53             item.machine = this;
     54 
     55             states.Add(typeof(T), item);
     56         }
     57     }
     58 
     59     /// <summary>
     60     /// 转换状态
     61     /// </summary>
     62     /// <typeparam name="T"></typeparam>
     63     public void ChangeState<T>() where T : State
     64     {
     65         if (states[typeof(T)] == null)
     66         {
     67             throw new System.Exception("状态机查找不到状态:" + typeof(T).Name);
     68         }
     69         if (!currentState.IsTransition(typeof(T)))
     70         {
     71             throw new System.Exception("状态机查找不到状态转换条件:" + typeof(T).Name);
     72         }
     73         currentState.Exit();
     74         currentState = states[typeof(T)];
     75         currentState.Enter();
     76     }
     77 
     78     /// <summary>
     79     /// 检查状态机是否包含某个状态
     80     /// </summary>
     81     /// <typeparam name="T"></typeparam>
     82     /// <returns></returns>
     83     public bool ContainsState<T>() where T : State
     84     {
     85         return states.ContainsKey(typeof(T));
     86     }
     87 
     88     /// <summary>
     89     /// 获得状态机的当前状态
     90     /// </summary>
     91     /// <typeparam name="T"></typeparam>
     92     /// <returns></returns>
     93     public T CurrentState<T>() where T : State
     94     {
     95         return (T)currentState;
     96     }
     97 
     98     /// <summary>
     99     /// 获取状态机某个状态
    100     /// </summary>
    101     /// <typeparam name="T"></typeparam>
    102     /// <returns></returns>
    103     public T GetState<T>() where T : State
    104     {
    105         if (states[typeof(T)] == null)
    106         {
    107             throw new System.Exception("状态机:" + name + "查找不到状态:" + typeof(T).Name);
    108         }
    109         return (T)states[typeof(T)];
    110     }
    111 
    112     /// <summary>
    113     /// 判断某个状态是否为状态机当前状态
    114     /// </summary>
    115     /// <typeparam name="T"></typeparam>
    116     /// <returns></returns>
    117     public bool IsCurrentState<T>() where T : State
    118     {
    119         return (currentState.GetType() == typeof(T)) ? true : false;
    120     }
    121     public bool IsCurrentState(System.Type T) { return (currentState.GetType() == T) ? true : false; }
    122 
    123 
    124     /// <summary>
    125     /// 移除状态机所有状态
    126     /// </summary>
    127     public void RemoveAllStates()
    128     {
    129         states.Clear();
    130     }
    131 
    132     /// <summary>
    133     /// 移除状态机某个状态
    134     /// </summary>
    135     /// <typeparam name="T"></typeparam>
    136     public void RemoveState<T>() where T : State
    137     {
    138         states.Remove(typeof(T));
    139     }
    140 
    141     /// <summary>
    142     /// 设置状态机当前状态
    143     /// </summary>
    144     /// <typeparam name="T"></typeparam>
    145     public void SetCurrentState<T>() where T : State
    146     {
    147         currentState = states[typeof(T)];
    148     }
    149 
    150     public virtual void Start()
    151     {
    152         Initialize();
    153     }
    154     public virtual void Update()
    155     {
    156         currentState.Execute();
    157     }
    158     public virtual void FixedUpdate()
    159     {
    160         currentState.FixedExecute();
    161     }
    162     public virtual void LateUpdate()
    163     {
    164         currentState.LateExecute();
    165     }
    166 
    167     // 状态机传递一些特殊的操作给状态
    168     public void OnCollisionEnter(Collision collision)
    169     {
    170         currentState.OnCollisionEnter(collision);
    171     }
    172     public void OnCollisionExit(Collision collision)
    173     {
    174         currentState.OnCollisionExit(collision);
    175 
    176     }
    177     public void OnCollisionStay(Collision collision)
    178     {
    179         currentState.OnCollisionStay(collision);
    180     }
    181     public void OnTriggerEnter(Collider collider)
    182     {
    183         currentState.OnTriggerEnter(collider);
    184     }
    185     public void OnTriggerExit(Collider collider)
    186     {
    187         currentState.OnTriggerExit(collider);
    188     }
    189     public void OnTriggerStay(Collider collider)
    190     {
    191         currentState.OnTriggerStay(collider);
    192     }
    193 
    194 
    195 }
    MachineBehaviour

    案例:

     1 using System.Collections;
     2 using System.Collections.Generic;
     3 using UnityEngine;
     4 
     5 public class PlayerIdleState : State
     6 {
     7     private bool isExecute = false;
     8     private PlayerStateMachine playerMachine { get { return (PlayerStateMachine)machine; } }
     9 
    10     public override void Initialize()
    11     {
    12         AddTransition<PlayerWalkState>();
    13     }
    14 
    15     public override void Enter()
    16     {
    17         Debug.Log("PlayerIdleState Enter");
    18         isExecute = false;
    19     }
    20 
    21     public override void Execute()
    22     {
    23         if (!isExecute)
    24         {
    25             Debug.Log("PlayerIdleState Execute");
    26             isExecute = true;
    27         }
    28         if (Input.GetKeyDown(KeyCode.S))
    29         {
    30             Debug.Log("转到状态PlayerWalkState");
    31             playerMachine.ChangeState<PlayerWalkState>();
    32         }
    33     }
    34 
    35     public override void Exit()
    36     {
    37         Debug.Log("PlayerIdleState Exit");
    38     }
    39 }
    PlayerIdleState
     1 using System.Collections;
     2 using System.Collections.Generic;
     3 using UnityEngine;
     4 
     5 public class PlayerWalkState : State
     6 {
     7     private bool isExecute = false;
     8     private PlayerStateMachine playerMachine { get { return (PlayerStateMachine)machine; } }
     9 
    10     public override void Initialize()
    11     {
    12         AddTransition<PlayerIdleState>();
    13     }
    14 
    15     public override void Enter()
    16     {
    17         Debug.Log("PlayerWalkState Enter");
    18         isExecute = false;
    19     }
    20 
    21     public override void Execute()
    22     {
    23         if (!isExecute)
    24         {
    25             Debug.Log("PlayerWalkState Execute");
    26             isExecute = true;
    27         }
    28         if (Input.GetKeyDown(KeyCode.S))
    29         {
    30             Debug.Log("转到状态PlayerIdleState");
    31             playerMachine.ChangeState<PlayerIdleState>();
    32         }
    33     }
    34 
    35     public override void Exit()
    36     {
    37         Debug.Log("PlayerWalkState Exit");
    38     }
    39 }
    PlayerWalkState
     1 using System;
     2 using System.Collections;
     3 using System.Collections.Generic;
     4 using UnityEngine;
     5 
     6 public class PlayerStateMachine : MachineBehaviour {
     7 
     8     public override void AddStates()
     9     {
    10         AddState<PlayerIdleState>();
    11         AddState<PlayerWalkState>();
    12 
    13         SetCurrentState<PlayerIdleState>();
    14     }
    15 }
    PlayerStateMachine

    运行截图:

  • 相关阅读:
    Hive中频繁报警的问题
    Hadoop中Namenode的HA查询和切换
    昨天面试遇到的一道C语言题
    【转】MapReduce的优化
    关于linux修改max user processes limits的问题
    Hadoop-2.6.0安装文档
    C#使用RabbitMQ
    windows配置Erlang环境
    【转】linux查看及修改文件权限以及相关
    (转)C#图解—PictureBox.SizeMode 属性
  • 原文地址:https://www.cnblogs.com/SeaSwallow/p/6588289.html
Copyright © 2011-2022 走看看