c 教学网站开发,网站如何提高转化率,湖北省建设厅官方网站八大员,淄博信息港聊天室网址该轮子由网络资源而来#xff0c;遵从作者开源意愿#xff0c;仅作免费学习和分享#xff0c;不作任何商业行为 #xff0c;本文不支持任何交易行为#xff0c;侵权删#xff01;#xff01;#xff01; 至于我为什么不将此文章设置为转载#xff0c;是因为该代码所在… 该轮子由网络资源而来遵从作者开源意愿仅作免费学习和分享不作任何商业行为 本文不支持任何交易行为侵权删 至于我为什么不将此文章设置为转载是因为该代码所在的网站早在2020年前就已经关闭了也就是该资源是祖传的很有意思吧 1.总览
请无视枚举中多出来的内容
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;/**
基于 Eric Dybsand 在《Game Programming Gems 1》第3.1章中的有限状态机系统作者Roberto Cezar Bianchini2010年7月使用方法1. 在相应的枚举中放置有限状态系统的转换和状态标签。2. 编写继承自 FSMState 的新类并在每个类中填充转换-状态对。这些对表示当 FSMSystem 处于状态 S1 时如果触发了转换 T且状态 S1 有从 T 到 S2 的转换FSMSystem 应该处于状态 S2。请记住这是一个确定性 FSM。一个转换不能导致两个不同的状态。方法 Reason 用于确定应该触发哪个转换。你可以在其他地方编写触发转换的代码并将此方法留空如果你觉得这更适合你的项目。方法 Act 包含 NPC 在此状态下应该执行的动作代码。你可以在其他地方编写动作代码并将此方法留空如果你觉得这更适合你的项目。3. 创建 FSMSystem 类的实例并添加状态。4. 从你的 Update 或 FixedUpdate 方法中调用 Reason 和 Act或你用于触发转换和使 NPC 在游戏中表现的任何方法。Unity 引擎的异步转换如 OnTriggerEnter、SendMessage也可以使用只需在事件发生时从你的 FSMSystem 实例中调用 PerformTransition 方法并传入正确的转换。软件按“原样”提供不提供任何形式的明示或暗示担保
包括但不限于适销性、特定用途适用性和非侵权的担保。
在任何情况下作者或版权持有人均不对任何索赔、损害或其他责任负责
无论是在合同诉讼、侵权行为或其他情况下
由软件或软件使用或其他交易引起或与之相关。
*//// summary
/// 在这个枚举中放置转换的标签。
/// 不要更改第一个标签 NullTransition因为 FSMSystem 类使用它。
/// /summary
public enum Transition {NullTransition 0, // 使用这个转换来表示系统中不存在的转换StartButtonClick,PauseButtonClick
}/// summary
/// 在这个枚举中放置状态的标签。
/// 不要更改第一个标签 NullStateID因为 FSMSystem 类使用它。
/// /summary
public enum StateID {NullStateID 0, // 使用这个 ID 来表示系统中不存在的状态Menu,Play,Pause,GameOver
}/// summary
/// 这个类代表有限状态系统中的状态。
/// 每个状态都有一个包含转换-状态对的字典
/// 显示当这个状态是当前状态时如果触发了转换
/// FSM 应该处于哪个状态。
/// 方法 Reason 用于确定应该触发哪个转换。
/// 方法 Act 包含 NPC 在这个状态下应该执行的动作代码。
/// /summary
public abstract class FSMState : MonoBehaviour {protected Ctrl ctrl;public Ctrl CTRL {set {ctrl value;}}protected FSMSystem fsm;public FSMSystem FSM {set {fsm value;}}protected DictionaryTransition, StateID map new DictionaryTransition, StateID();protected StateID stateID;public StateID ID {get {return stateID;}}public void AddTransition(Transition trans, StateID id) {// 检查参数是否无效if (trans Transition.NullTransition) {Debug.LogError(FSMState 错误NullTransition 不允许作为真实的转换);return;}if (id StateID.NullStateID) {Debug.LogError(FSMState 错误NullStateID 不允许作为真实的 ID);return;}// 由于这是一个确定性 FSM// 检查当前转换是否已经在字典中if (map.ContainsKey(trans)) {Debug.LogError(FSMState 错误状态 stateID.ToString() 已经有转换 trans.ToString() 无法分配给另一个状态);return;}map.Add(trans, id);}/// summary/// 这个方法从该状态的映射中删除一个转换-状态对。/// 如果转换不在该状态的映射中将打印错误信息。/// /summarypublic void DeleteTransition(Transition trans) {// 检查 NullTransitionif (trans Transition.NullTransition) {Debug.LogError(FSMState 错误不允许使用 NullTransition);return;}// 在删除之前检查该对是否在映射中if (map.ContainsKey(trans)) {map.Remove(trans);return;}Debug.LogError(FSMState 错误传递给 stateID.ToString() 的转换 trans.ToString() 不在该状态的转换列表中);}/// summary/// 如果这个状态接收到一个转换这个方法返回 FSM 应该处于的新状态/// /summarypublic StateID GetOutputState(Transition trans) {// 检查映射中是否有这个转换if (map.ContainsKey(trans)) {return map[trans];}return StateID.NullStateID;}/// summary/// 这个方法用于在进入状态之前设置状态条件。/// 它在 FSMSystem 类将其分配为当前状态之前自动调用。/// /summarypublic virtual void DoBeforeEntering() {}/// summary/// 这个方法用于在 FSMSystem 切换到另一个状态之前/// 执行任何必要的操作如重置变量。/// 它在 FSMSystem 切换到新状态之前自动调用。/// /summarypublic virtual void DoBeforeLeaving() {}/// summary/// 这个方法决定状态是否应该转换到其列表中的另一个状态。/// NPC 是一个引用指向由这个类控制的对象。/// /summarypublic virtual void Reason() {}/// summary/// 这个方法控制 NPC 在游戏世界中的行为。/// NPC 执行的每个动作、移动或交流都应该放在这里。/// NPC 是一个引用指向由这个类控制的对象。/// /summarypublic virtual void Act() {}} // class FSMState/// summary
/// FSMSystem 类代表有限状态机类。
/// 它有一个包含 NPC 状态的列表和添加、删除状态以及更改当前状态的方法。
/// /summary
public class FSMSystem {private ListFSMState states;// 改变 FSM 状态的唯一方法是执行转换// 不要直接更改 CurrentStateprivate StateID currentStateID;public StateID CurrentStateID {get {return currentStateID;}}private FSMState currentState;public FSMState CurrentState {get {return currentState;}}public FSMSystem() {states new ListFSMState();}public void SetCurrentState(FSMState s) {currentState s;currentStateID s.ID;s.DoBeforeEntering();}/// summary/// 这个方法将新状态放入 FSM 中/// 如果状态已经在列表中则打印错误信息。/// 添加的第一个状态也是初始状态。/// /summarypublic void AddState(FSMState s, Ctrl ctrl) {// 在删除之前检查空引用if (s null) {Debug.LogError(FSM 错误不允许空引用);}s.FSM this;s.CTRL ctrl;// 插入的第一个状态也是初始状态// 模拟开始时机器所处的状态if (states.Count 0) {states.Add(s);return;}// 如果状态不在列表中则将其添加到列表中foreach (FSMState state in states) {if (state.ID s.ID) {Debug.LogError(FSM 错误无法添加状态 s.ID.ToString() 因为状态已经被添加);return;}}states.Add(s);}/// summary/// 如果状态存在这个方法从 FSM 列表中删除一个状态/// 如果状态不在列表中则打印错误信息。/// /summarypublic void DeleteState(StateID id) {// 在删除之前检查 NullStateif (id StateID.NullStateID) {Debug.LogError(FSM 错误不允许使用 NullStateID 作为真实状态);return;}// 搜索列表并删除其中的状态foreach (FSMState state in states) {if (state.ID id) {states.Remove(state);return;}}Debug.LogError(FSM 错误无法删除状态 id.ToString() 。它不在状态列表中);}/// summary/// 这个方法尝试根据当前状态和传递的转换来改变 FSM 所处的状态。/// 如果当前状态没有传递的转换的目标状态则打印错误信息。/// /summarypublic void PerformTransition(Transition trans) {// 在更改当前状态之前检查 NullTransitionif (trans Transition.NullTransition) {Debug.LogError(FSM 错误不允许使用 NullTransition 作为真实转换);return;}// 检查当前状态是否有传递的转换StateID id currentState.GetOutputState(trans);if (id StateID.NullStateID) {Debug.LogError(FSM 错误状态 currentStateID.ToString() 没有目标状态 对于转换 trans.ToString());return;}// 更新 currentStateID 和 currentStatecurrentStateID id;foreach (FSMState state in states) {if (state.ID currentStateID) {// 在设置新状态之前进行状态的后处理currentState.DoBeforeLeaving();currentState state;// 在状态可以推理或行动之前重置其到所需条件currentState.DoBeforeEntering();break;}}} // PerformTransition()} //class FSMSystem2.功能分述 功能定义了状态转换的标签。NullTransition 用于表示不存在的转换。
public enum Transition
{NullTransition 0, // 使用这个转换来表示系统中不存在的转换StartButtonClick,PauseButtonClick
}功能定义了状态的标签。NullStateID 用于表示不存在的状态。
public enum StateID
{NullStateID 0, // 使用这个 ID 来表示系统中不存在的状态Menu,Play,Pause,GameOver
}功能
AddTransition添加状态转换。DeleteTransition删除状态转换。GetOutputState获取转换后的状态。DoBeforeEntering进入状态前的设置。DoBeforeLeaving离开状态前的设置。Reason决定是否进行状态转换。Act控制 NPC 在当前状态下的行为。 public abstract class FSMState : MonoBehaviour
{protected Ctrl ctrl;public Ctrl CTRL { set { ctrl value; } }protected FSMSystem fsm;public FSMSystem FSM { set { fsm value; } }protected DictionaryTransition, StateID map new DictionaryTransition, StateID();protected StateID stateID;public StateID ID { get { return stateID; } }public void AddTransition(Transition trans, StateID id){// 检查参数是否无效if (trans Transition.NullTransition){Debug.LogError(FSMState 错误NullTransition 不允许作为真实的转换);return;}if (id StateID.NullStateID){Debug.LogError(FSMState 错误NullStateID 不允许作为真实的 ID);return;}// 检查当前转换是否已经在字典中if (map.ContainsKey(trans)){Debug.LogError(FSMState 错误状态 stateID.ToString() 已经有转换 trans.ToString() 无法分配给另一个状态);return;}map.Add(trans, id);}public void DeleteTransition(Transition trans){// 检查 NullTransitionif (trans Transition.NullTransition){Debug.LogError(FSMState 错误不允许使用 NullTransition);return;}// 在删除之前检查该对是否在映射中if (map.ContainsKey(trans)){map.Remove(trans);return;}Debug.LogError(FSMState 错误传递给 stateID.ToString() 的转换 trans.ToString() 不在该状态的转换列表中);}public StateID GetOutputState(Transition trans){// 检查映射中是否有这个转换if (map.ContainsKey(trans)){return map[trans];}return StateID.NullStateID;}public virtual void DoBeforeEntering() { }public virtual void DoBeforeLeaving() { }public virtual void Reason() { }public virtual void Act() { }
}功能
AddState添加新状态到 FSM。DeleteState从 FSM 中删除状态。SetCurrentState设置当前状态。PerformTransition执行状态转换。 public class FSMSystem
{private ListFSMState states;// 改变 FSM 状态的唯一方法是执行转换// 不要直接更改 CurrentStateprivate StateID currentStateID;public StateID CurrentStateID { get { return currentStateID; } }private FSMState currentState;public FSMState CurrentState { get { return currentState; } }public FSMSystem(){states new ListFSMState();}public void SetCurrentState(FSMState s){currentState s;currentStateID s.ID;s.DoBeforeEntering();}public void AddState(FSMState s, Ctrl ctrl){// 在删除之前检查空引用if (s null){Debug.LogError(FSM 错误不允许空引用);}s.FSM this;s.CTRL ctrl;// 插入的第一个状态也是初始状态// 模拟开始时机器所处的状态if (states.Count 0){states.Add(s);return;}// 如果状态不在列表中则将其添加到列表中foreach (FSMState state in states){if (state.ID s.ID){Debug.LogError(FSM 错误无法添加状态 s.ID.ToString() 因为状态已经被添加);return;}}states.Add(s);}public void DeleteState(StateID id){// 在删除之前检查 NullStateif (id StateID.NullStateID){Debug.LogError(FSM 错误不允许使用 NullStateID 作为真实状态);return;}// 搜索列表并删除其中的状态foreach (FSMState state in states){if (state.ID id){states.Remove(state);return;}}Debug.LogError(FSM 错误无法删除状态 id.ToString() 。它不在状态列表中);}public void PerformTransition(Transition trans){// 在更改当前状态之前检查 NullTransitionif (trans Transition.NullTransition){Debug.LogError(FSM 错误不允许使用 NullTransition 作为真实转换);return;}// 检查当前状态是否有传递的转换StateID id currentState.GetOutputState(trans);if (id StateID.NullStateID){Debug.LogError(FSM 错误状态 currentStateID.ToString() 没有目标状态 对于转换 trans.ToString());return;}// 更新 currentStateID 和 currentStatecurrentStateID id;foreach (FSMState state in states){if (state.ID currentStateID){// 在设置新状态之前进行状态的后处理currentState.DoBeforeLeaving();currentState state;// 在状态可以推理或行动之前重置其到所需条件currentState.DoBeforeEntering();break;}}} // PerformTransition()} //class FSMSystem