Unity状态机的实现,以《塔防》为例
什么是有限状态机?
通俗点讲,有限状态机是:将对象的状态(攻击、闲置、晕眩)的实现代码,提取出来,封装成状态。由状态机负责在各个状态之间调度。
对象持有状态管理类(状态机)的引用,与具体的状态解耦。
OK,那接下来开始设计一个塔的状态,我们有一个父类FiniteState,状态机只和父类交互,屏蔽了状态具体实现

塔与状态是一对一的关系,也就是说,在塔创建的时候,全部状态已经生成好了(GenerateStateList方法), 我们根据状态的枚举类进行切换。
using System.Collections.Generic; /// <summary>
/// 塔的状态机工具类
/// </summary>
public class TowerStateHelper
{
/// <summary>
/// 状态个数
/// </summary>
private const int STATE_COUNT = ; /// <summary>
/// 创建状态集合
/// </summary>
/// <param name="tower">作用对象</param>
/// <returns></returns>
public static Dictionary<StateType, FiniteState> GenerateStateList(TowerBase tower)
{
Dictionary<StateType, FiniteState> stateList = new Dictionary<StateType, FiniteState>(STATE_COUNT); stateList.Add(StateType.Idle, new StateIdle() { TargetTower = tower, StateTypeId = StateType.Idle });
stateList.Add(StateType.Guard, new StateGuard() { TargetTower = tower, StateTypeId = StateType.Guard });
stateList.Add(StateType.Attack, new StateAttack() { TargetTower = tower, StateTypeId = StateType.Attack });
stateList.Add(StateType.Spell, new StateSpell() { TargetTower = tower, StateTypeId = StateType.Spell }); return stateList;
}
} /// <summary>
/// 状态类型
/// </summary>
public enum StateType
{
/// <summary>
/// 不可用
/// </summary>
Innit, /// <summary>
/// 闲置
/// </summary>
Idle, /// <summary>
/// 攻击
/// </summary>
Attack, /// <summary>
/// 警惕
/// </summary>
Guard, /// <summary>
/// 吟唱
/// </summary>
Spell
}
状态机,它的职责是负责在各个状态之间进行调度
using System.Collections.Generic; /// <summary>
/// 状态机
/// </summary>
public class TowerStateMachine
{
#region 公共属性 /// <summary>
/// 追溯前面的状态
/// </summary>
public StateType PreviousStateType
{
get; set;
} #endregion #region 私有属性
/// <summary>
/// 全局状态
/// </summary>
private FiniteState _globalState; /// <summary>
/// 当前状态
/// </summary>
private FiniteState _currentState; /// <summary>
/// 状态列表
/// </summary>
private Dictionary<StateType, FiniteState> _stateList; #endregion #region 重写事件 /// <summary>
/// 初始化方法
/// </summary>
/// <param name="globalState">全局状态</param>
/// <param name="newStateType">当前状态</param>
public TowerStateMachine(TowerBase tower, FiniteState globalState, StateType newStateType)
{
PreviousStateType= StateType.Innit;
_stateList = TowerStateHelper.GenerateStateList(tower); if (null != globalState)
{
globalState.OnEnter();
_globalState = globalState;
} _stateList[newStateType].OnEnter();
_currentState = _stateList[newStateType];
} #endregion #region 公共方法 /// <summary>
/// 执行
/// </summary>
public void Excute()
{
if (null != _globalState)
_globalState.OnExcute(); if (null != _currentState)
_currentState.OnExcute();
} /// <summary>
/// 改变状态
/// </summary>
/// <param name="newStateType"></param>
public void ChangeStatus(StateType newStateType)
{
if (newStateType == _currentState.StateTypeId)
return; PreviousStateType = _currentState.StateTypeId;
_currentState.OnExit(); _stateList[newStateType].OnEnter();
_currentState = _stateList[newStateType];
} #endregion
}
状态基类,我们定义了进入、OnExcute(每次update被调用)、退出方法
/// <summary>
/// 状态基类
/// </summary>
public abstract class FiniteState
{
/// <summary>
/// 状态机类型
/// </summary>
public StateType StateTypeId { get; set; } /// <summary>
/// 塔对象
/// </summary>
public TowerBase TargetTower { get; set; } /// <summary>
/// 进入
/// </summary>
public abstract void OnEnter(); /// <summary>
/// 执行
/// </summary>
public abstract void OnExcute(); /// <summary>
/// 退出
/// </summary>
public abstract void OnExit();
}
调用对象
//声明
private TowerStateMachine _stateMachine; //初始化
_stateMachine = new TowerStateMachine(this, null, StateType.Idle); //在Update方法里调用
_stateMachine.Excute();
状态的切换由具体状态类满足条件自动触发、或者手动触发都可以。
Unity状态机的实现,以《塔防》为例的更多相关文章
- 使用Unity创建塔防游戏(Part2)
How to Create a Tower Defense Game in Unity – Part 2 原文地址:https://www.raywenderlich.com/107529/unity ...
- 使用Unity创建塔防游戏(Part1)
How to Create a Tower Defense Game in Unity - Part1 原文作者:Barbara Reichart 文章原译:http://www.cnblogs.co ...
- 使用unity创建塔防游戏(原译)(part1)
塔防游戏非常地受欢迎,木有什么能比看着自己的防御毁灭邪恶的入侵者更爽的事了. 在这个包含两部分的教程中,你将使用Unity创建一个塔防游戏. 你将会学到如何: 创建一波一波的敌人 使敌人随着路标移动 ...
- Unity塔防游戏开发
Unity3D塔防开发流程 配置环境及场景搭建编程语言:C#,略懂些许设计模式,如果不了解设计模式,BUG More开发工具:Unity3D编辑器.Visual Studio编译器开发建议:了解Uni ...
- 使用Unity创建塔防游戏(Part3)—— 项目总结
之前我们完成了使用Unity创建塔防游戏这个小项目,在这篇文章里,我们对项目中学习到的知识进行一次总结. Part1的地址:http://www.cnblogs.com/lcxBlog/p/60759 ...
- Unity《ATD》塔防RPG类3D游戏架构设计(二)
目录 <ATD> 游戏模型 <ATD> 游戏逻辑 <ATD> UI/HUD/特效/音乐 结语 前篇:Unity<ATD>塔防RPG类3D游戏架构设计(一 ...
- Unity《ATD》塔防RPG类3D游戏架构设计(一)
目录 <ATD> 游戏简介 <ATD> 整体结构 <ATD> 游戏机制 Buff机制 Skill机制(技能机制) 仇恨机制 <ATD> 游戏模型 策划案 ...
- Unity塔防游戏的创建
看了下塔防游戏的教程,比我想像的还简单一些,有些收获: (1)敌人的移动路径,其时比较简单,用了N个Empty GameObject作为路径点,然后做一个总的Empty GameObject 作为父级 ...
- Unity3D学习笔记(十七):IK动画、粒子系统和塔防
新动画系统: 反向动力学动画(IK功能): 魔兽世界(头部动画),神秘海域(手部动画),人类一败涂地(手部动画) 如何启用(调整) 1.必须是新动画系统Animator 设置头.手.肘的目标点 2.动 ...
- Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(三)
一.前提: 完成前一篇的内容. 具体参考:Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(二)篇 二.本篇目标: l 说说游戏中各种角色的动作.属性以及重构思路 l 进行代码重构让色狼大叔和 ...
随机推荐
- Hibernate_day02--Hibernate事务操作_api使用
Hibernate事务操作 事务相关概念 1 什么是事务 事务是操作中最基本的单元,表示一组操作要么都成功,有一个失败那么所有都失败.最典型的场景:银行转账 2 事务特性 原子性 一致性 隔离性 持久 ...
- Hibernate_day01--课程安排_Hibernate概述_Hibernate入门
Hibernate_day01 Hibernate课程安排 今天内容介绍 WEB内容回顾 JavaEE三层结构 MVC思想 Hibernate概述 什么是框架 什么是hibernate框架(重点) 什 ...
- poj_2349 Kruskal 最小生成树
题目大意 给定N个点的坐标,这N个点之间需要进行通讯.通讯方式可以采用卫星通信或无线通信,若两点之间采用为卫星通信,则两点之间的距离无限制,若采用无线通讯,则两点之间的距离不能大于某个值D. ...
- 常用SEO优化技巧
SEO是指搜索引擎优化 搜索引擎优化是一种利用搜索引擎的搜索规则来提高目前网站在有关搜索引擎内的自然排名的方式.SEO的目的理解是:为网站提供生态式的自我营销解决方案,让网站在行业内占据领先地位,从而 ...
- 160608、mysql距离函数st_distance
随着近几年各类移动终端的迅速普及,在手机移动定位app中,附近的人,附近的地点功能十分常见,基于地理位置的服务(LBS)和相关应用也越来越多,而支撑这些应用的最基础技术之一,就是基于地理位置信息的处理 ...
- 解决;R语言使用sqldf库是报错"Failed to connect to database: Error: Access denied for user '..'@'localhost' (using password: NO) Error in !dbPreExists : invalid argument type"
原因:在使用sqldf时,不需要加载RMySQL库 解决方案:在控制台执行释放RMySQL库加载 detach("package:RMySQL", unload=T);
- Nagle's Algorithm and TCP_NODELAY
w非全尺寸分组的发送条件 HTTP The Definitive Guide TCP has a data stream interface that permits applications to ...
- 剑指Offer——二叉树的下一个结点
题目描述: 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 分析: 如果该结点存在右子树,那么返回右子树的最左结 ...
- leetcode 旋转单链表
Given a linked list, rotate the list to the right by k places, where k is non-negative. Example 1: I ...
- shell awk实战
一.文本处理 1.按行提取关键字频次(如取第5列) awk 'BEGIN{FS="|"} {a[$5]+=1;} END {for(i in a) print i ":& ...