Unity有限状态机详解
这阵子用到了有限状态机,于是花了一段时间研究了一下。在这里我会详细的讲解有限状态机的原理以及如何编写一个有限状态机。
有限状态机算是Unity开发中一个比较重要的技巧了。那什么什么是有限状态机呢?在游戏中,我们可能会遇到各种各样的状态,这里我以一个人人物为例,我们可能要经常判断人物的生命状态或者人物的运动状态,然后做相应的操作。
我们可以用Switch语句来获取状态,并且通过特定的方法来设置状态。但我们可能要在项目的很多地方的调用这段Switch方法,或者设置当前人物的状态。当状态比较多的时候,对状态的管理和获取也会变得更加麻烦。
Switch(人物生命状态)
{Case Alive:do something();Case Alive:do something();break;
}Switch(人物运动状态)
{Case Run:do something();Case Idle:do something();Case Walk:do something();break;
}
所以这个时候,我们需要一个有限状态机(Finite State Machine)来集中的管理状态(State)。现在我们来看看如何设计一个有限状态机。
有限状态机包含两个部分①状态集(FSMState),②状态管理机(FSMSystem),我们先从状态集开始设计。
①状态集(FSMState)的设计
状态基代表一组状态的集合,比如上面的人物,他的状态集是这样的
enum PersonLifeState
{died,alive
}enum PersonSportState
{run,idle,walk
}
一个游戏当中可能需要多个状态集,所以我们在设计FSMState,最好将他设计为抽象类,这样就能通过继承FSMState,拥有一些公共的属性和方法,同时又有自己特定的状态。我设计的方式如下,通过一个List,可以让FSMState的派生类添加属于自己特有的状态,同时有一个变量保存当前的State。
public abstract class FSMState
{private List<State> list= new List<State>();private State curState;/*添加状态集中的状态*/public void AddState(State state){if (list.Contains(state)){return;}list.Add(state);}/*设置当前的状态,注意这里为私有方法,这样可以让派生类无法直接设置状态,而是让状态机来统一设置*/private bool setCurState(State state){if(list.Contains(state)){curState=state;return true;}else{return false;}}……//可以自己根据业务,设计一些共有的抽象方法
}
现在有了状态集了,我们还需要设计状态(State)。一个游戏中有各种各样的状态,我们要怎么设计呢?我们可以把特定集合的状态放在不同的枚举里,不过,我设计的是将所有状态放在一个枚举类里面。代码如下。
public enum State
{died, alive,walk,run,stop
}`
这样,我们就可以继承这个FSMState基类,然后添加特定的状态了。
人物生命状态
public class PersonLifeState :FSMState
{……
}/*PersonLifeState 添加自己特有的状态*/
PersonLifeState personLife= new PersonLifeState ();
personLife.AddState(State.died);
personLife.AddState(State.alive);
人物运动状态
public class PersonSportState :FSMState
{……
}/*personSport 添加自己特有的状态*/
PersonSportState personSport = new PersonSportState ();
personSport .AddState(State.walk);
personSport .AddState(State.run);
personSport .AddState(State.stop );
现在,FSMState就设计好了,我们在来看看如何设计一个FSMSystem
①状态管理机(FSMSystem)的设计
一个状态管理机主要的功能有这两点
- 能够添加和删除状态集(FSMState)
- 能够切换和获取某个状态集(FSMState)当前的状态(State)
知道了FSMSystem最主要的功能,我们现在就可以来自己设计一个了。我设计的FSMState代码如下
public class FSMSystem
{/*通过一个List专门用来存储FSMState */private List<FSMState> statesList=new List<>();/*添加FSMState的方法 */public void AddState(FSMState states){/*做空判断检测*/if (statesList== null){Debug.LogError("FSM ERROR");}/*当states为空时直接添加*/if (stateList.Count == 0){statesList.Add(states);return;}/*当states不为空时,检查是否重复*/if(!statesList.contans(states)){states.Add(s);}}/*删除状态集合*/public void DeleteState(FSMState states){if(!statesList.contans(states)){states.Remove(states);}}/*获取某个状态集的当前状态*/public State GetCurState(FSMState states){ if(!statesList.contans(states)){states.getCurState();}}/*改变某个状态集的当前状态*/public void ChangeState(FSMState states,State state){if(!statesList.contans(states)){states.setCurState();}}}
这样我们就把状态机FSMSystem设计好了,我们将FSMState的派生类强行转换成FSMState基类,就能让FSMSystem统一进行管理了。上面的代码只是我设计有限状态机的一种思路,用来参考就行了。只要掌握了有限状态机的原理,你可以自己设计符合业务逻辑的状态机。虽然有限状态机比switch的方法要复杂很多,但是却能大大的简化代码逻辑。学会并使用有限状态机还是蛮重要的。
Unity有限状态机详解相关推荐
- Unity下FSM有限状态机详解
FSM有限状态机详解 文章目录 FSM有限状态机详解 FSM的定义 FSM的适用性 FSM的设计分析 状态转换表的使用 状态和条件的标识符Id 条件基类的设计 FSMTrigger 状态基类的设计 F ...
- Unity——RectTransform详解
Unity--RectTransform详解 目录 1.Anchor(Min,Max) 2.绝对与相对布局 3.Pivot 4.Offset(Min,Max) 5.SizeDelta 6.rect 7 ...
- Unity 灯光系统详解
Unity 灯光系统详解 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人! (拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分享. ...
- Unity快捷键详解
Unity快捷键详解 -- -- 目录: 一:常用快捷键 二:快捷键(官方文档) 三:快捷键查看及相关操作(编辑器) 四:全局快捷键和上下文快捷键 -- -- 一:常用快捷键 补充:Ctrl+Shif ...
- 【Unity开发小技巧】FMS有限状态机详解
欢迎加入Unity业内qq交流群:956187480 qq扫描二维码加群 在实际开发中很多时候对某类别的对象都需要有多种状态的管理和切换,这个时候我们就可以引入FMS状态机概念,有限状态机主要有三要素 ...
- 确定有限状态机和非确定有限状态机详解 包含Java实现源码(Nondeterministic finite automata)
本文将讲解确定有限自动状态机和非确定有限自动状态机的特点和区别.将结合图片例子重点讲解什么是非确定有限自动状态机.最后讲解如何将非确定状态机转换为确定的状态机.多图预警!! 有限自动状态机可以分为确定 ...
- [专栏精选]Unity刚体详解
本文节选自洪流学堂公众号专栏<郑洪智的Unity2018课>,未经允许不可转载. 洪流学堂公众号回复专栏,查看更多专栏文章. 洪流学堂,让你快人几步.你好,我是郑洪智. 从这节课开始,我会 ...
- 有限状态机详解(转载)
以前总觉得有限状态机和无限状态机非常的难理解,原来也就是自己一直没有一个直观的认识,今天看到一篇博客,总算对有限状态机入门了.一看就懂. 转载地址:http://blog.csdn.net/zqixi ...
- Unity API详解——Application类
Unity对API的合理利用不仅可以减轻编码负担,而且往往可以提高程序的运行效率,尽管官方给出了较为丰富的API文档,然而这并不能满足实际开发的需要,因为官方给出的API解释往往只描述相应的API的主 ...
最新文章
- HTML中将px转换为em的语法,在JavaScript中转换EM为PX(并获得默认字体大小)
- [译]开始对Angular App进行单元测试(1)
- 需求评审五个维度框架分析及其带来的启示-3-典型需求评审
- 关于 SAP UI5 系统测试工具 UIVeri5 的 Chromedriver 版本问题
- Java and Jakarta - Hybris
- 解决vue项目在ie浏览器中不显示的问题
- 【ElasticSearch】Es 源码之 SearchTransportService 源码解读
- 网络拓扑发现原理研究
- 从TextBox的升级看VB6与VB2010的不同~
- 【Altium Designer10详细安装】
- 初一上册数学用计算机进行运算,初一上册数学
- office2016显示已经激活,但每次打开都跳出激活页面
- 新面貌,新征程—读《新程序员》有感
- div四角边框直角、倒角、 圆角、倒圆角
- 新手学java用什么电脑?需要安装什么软件
- 异构数据源离线同步工具之DataX的安装部署
- iOS自动化_免越狱_免签名
- 输入命题p和q的真值,求p、q的合取、析取、异或、蕴含和等值命题的真值
- P1216 数字金字塔
- kali虚拟机自带burp抓包物理机
热门文章
- 2021-2027全球与中国动态IV输液泵市场现状及未来发展趋势
- oracle安装问题--未找到11.2.0服务器端
- DETR训练自己的数据集
- 复述、听说读写与学习
- What's the difference between specially and especially?
- 蚂蚁网商银行测开,前两轮面经分享(Java)
- 海外移动APP开发常用的三方平台
- Android 基于ijkplayer+Rxjava+Rxandroid+Retrofit2.0+MVP+Material Design的android万能播放器aaa
- oracle impdp优化,ORACLE IMPDP优化调整
- (2)android MediaPlayer 和Nupalyer、MediaCodec、OMX关系