笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》电子工业出版社等。

CSDN视频网址:http://edu.csdn.net/lecturer/144

下面给读者讲解在游戏开发中经常使用的FSM有限状态机的实现,有限状态机在状态切换中使用的非常多,比如足球游戏,动作游戏等。角色在游戏场景中经常需要动作的切换,比如Idle,Run,Attack,Skill等,这些技能状态之间的切换,我们通常会使用FSM去处理。我们在游戏中将动作切换和技能切换放在一起使用FSM处理,下面通过代码的方式给读者进行封装处理:

 public interface EntityFSM{bool CanNotStateChange{set;get;}FsmState State { get; }void Enter(Ientity entity , float stateLast);bool StateChange(Ientity entity , EntityFSM state);void Execute(Ientity entity);void Exit(Ientity Ientity);}

先定义一个抽象类用于具体状态的实现,游戏中的具体状态,我们通过枚举的方式定义如下:

 public enum FsmState {FSM_STATE_FREE,FSM_STATE_RUN,      FSM_STATE_SING,FSM_STATE_RELEASE,  FSM_STATE_LEADING,  FSM_STATE_LASTING,FSM_STATE_DEAD,       FSM_STATE_ADMOVE,   FSM_STATE_FORCEMOVE,    FSM_STATE_RELIVE,   FSM_STATE_IDLE,}

下面告诉大家如何使用我们具体的动作状态切换,具体实现就是继承上面定义的接口:

 public class EntityIdleFSM : EntityFSM{public static readonly EntityFSM Instance = new EntityIdleFSM();public FsmState State{get       {           return FsmState.FSM_STATE_IDLE;}}public bool CanNotStateChange{set;get;}public bool StateChange(Ientity entity , EntityFSM fsm) {return CanNotStateChange;}public void Enter(Ientity entity , float last)   {       entity.OnEnterIdle();}public void Execute(Ientity entity)   {       if (EntityStrategyHelper.IsTick(entity, 3.0f))      {       entity.OnFSMStateChange(EntityFreeFSM.Instance);        }}public void Exit(Ientity entity){}}

在这个函数中使用了一个接口Ientity,其实它主要实现的是状态之间的切换,下面就把该类的主要功能实现如下所示:

 /// <summary>/// 状态改变/// </summary>/// <param name="fsm"></param>/// <param name="last"></param>public void OnFSMStateChange(EntityFSM fsm, float last){if (this.FSM != null && this.FSM.StateChange(this, fsm)){return;}if (this.FSM == fsm && this.FSM != null && this.FSM.State == FsmState.FSM_STATE_DEAD){return;}if (this.FSM != null){this.FSM.Exit(this);}if (this.FSM != null)this.RealEntity.FSMStateName = fsm.ToString();this.FSM = fsm;StrategyTick = Time.time;this.FSM.Enter(this, last);}public void OnFSMStateChange(EntityFSM fsm){if (this.FSM != null && this.FSM.StateChange(this, fsm)){return;}if (this.FSM == fsm && this.FSM != null && (this.FSM.State == FsmState.FSM_STATE_DEAD)){return;}if (this.FSM != null){this.FSM.Exit(this);}this.FSM = fsm;if (this.FSM != null)this.RealEntity.FSMStateName = fsm.ToString();StrategyTick = Time.time;this.FSM.Enter(this, 0.0f);}

该类还提供了各个动作的接口,实现如下所示:

 public virtual void OnEnterIdle(){this.RealEntity.PlayerAnimation("idle");}/// <summary>/// Run状态进入时调用/// </summary>public virtual void OnEnterMove(){}

这个RealEntity类实现的是具体的动作或者是新动画触发函数封装事例代码如下所示:

 public void PlayerIdleAnimation()   {   if (this.animation == null)   {       return;      }PlayerAnimation("idle");this.animation.PlayQueued("free");}public void PlayerFreeAnimation(){if (this.animation == null){return;}PlayerAnimation("free");}public void PlayerRunAnimation(){if (this.animation == null) {return;}PlayerAnimation("walk");}

技能的接口实现跟这个类似,代码如下所示:

 public class EntityReleaseSkillFSM : EntityFSM{public static readonly EntityFSM Instance = new EntityReleaseSkillFSM();public FsmState State{get{return FsmState.FSM_STATE_RELEASE;}}public bool CanNotStateChange{set;get;}public bool StateChange(Ientity entity , EntityFSM fsm){return CanNotStateChange;}public void Enter(Ientity entity , float last){//Debug.LogError("prepareplayskill enter!");entity.OnEntityReleaseSkill();}public void Execute(Ientity entity){//entity.OnEntityPrepareAttack ();}public void Exit(Ientity entity){}}

这样我们的FSM状态机就实现完成了,使用该框架开发了多款游戏,效果如下:

Unity3D优化技巧系列八相关推荐

  1. Unity3D优化技巧系列一

    笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D ...

  2. Unity3D优化技巧系列三

    笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D ...

  3. Unity3D优化技巧系列二

    笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D ...

  4. Unity3D优化技巧系列七

    笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D ...

  5. 系列笔记 | 深度学习连载(5):优化技巧(下)

    点击上方"AI有道",选择"星标"公众号 重磅干货,第一时间送达 深度学习中我们总结出 5 大技巧: 本节继续从第三个开始讲起. 3. Early stoppi ...

  6. php 随机在文章中添加锚文本_seo网站优化技巧之:8种优质锚文本的做法

    众所周知,质量最高的外链就是锚文本形式的外链,这种外链又称为锚链,当锚文本中嵌入了我们的目标关键词之后,这种锚链的权重传递效率最高.锚文本链接的质量高低,对关键词排名及网站权重的影响非常大. seo网 ...

  7. jQuery 性能优化技巧

    原文地址:jQuery 性能优化技巧 博客地址:www.extlight.com 一.使用最新版本 jQuery 类库 二.合理使用选择器 # 推荐使用 $("#id") # 可以 ...

  8. MySQL 性能优化技巧

    原文地址:MySQL 性能优化技巧 博客地址:www.extlight.com 一.背景 最近公司项目添加新功能,上线后发现有些功能的列表查询时间很久.原因是新功能用到旧功能的接口,而这些旧接口的 S ...

  9. mysql数据库优化大全_MySQL数据库优化技巧大全

    简介: MySQL数据库优化技巧大全 MySQL优化三大方向 ① 优化MySQL所在服务器内核(此优化一般由运维人员完成). ② 对MySQL配置参数进行优化(my.cnf)此优化需要进行压力测试来进 ...

最新文章

  1. Py之nltk:nltk包的简介、安装、使用方法、代码实现之详细攻略
  2. C++ Primer 5th笔记(chap 17 标准库特殊设施)指定浮点数记数法
  3. optee3.12.0 qemu_v8的环境搭建篇(ubuntu20.04)
  4. python用tsne降维_哈工大硕士实现了 11 种经典数据降维算法,源代码库已开放
  5. Eclipse 插件开发 向导
  6. [objective-c] 08 - 内存管理
  7. php中奖概率算法,可用于刮刮卡,大转盘等抽奖算法
  8. ionic 组件之二维码扫描
  9. [Ext JS] 组件浮动一篇通(floating、alignTo)
  10. vue从哪看组件版本_VUE源码解析之路
  11. 制作Camtasia 2020击键标记动画
  12. 详解YUV系列(二)--YUV422
  13. [编程与人生的韵味]注重实效的哲学
  14. bzoj 1415: [Noi2005]聪聪和可可
  15. 26个字母大小写转换
  16. 【190115】VC++ AVI视频播放程序源代码
  17. 智能配时、图片识别…AI为你的春运保驾护航!
  18. 用户商家对刷脸支付好评不断普及指日可待
  19. accumulate的用法
  20. C语言之复合类型下卷(十九)(自然法则)(2023)

热门文章

  1. 夜光带你走进python开发 (三十九)传奇语言
  2. middel在c语言中的作用,Middle和medium的区别
  3. 小学学计算机应该学什么礼物,小学毕业礼物排行榜,运动学习两不耽误
  4. 我提了离职,公司给我涨薪了,还能待下去吗?
  5. 认知升级篇:别说你懂《刻意练习》
  6. 中科蓝讯AB536X系列芯片PWM使用说明
  7. spark报错 java.lang.NullPointerException: Null value appeared in non-nullable field:top level Product
  8. 单目标测向系统中CRLB推导及Matlab仿真验证
  9. 功能:输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举)(如180的质因子为2 2 3 3 5 )
  10. 邮箱无法登陆的解决方法