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 进行代码重构让色狼大叔和 ...
随机推荐
- VC++为你的程序增加内存泄露检测
使用方法: C++ Code 12345678910111213141516171819202122232425262728293031323334353637383940414243444546 ...
- 编程之美 set 10 队列中取最大值操作问题
题目 假设有这样一个拥有三个操作的队列 1. Enqueue(v) 2. Dequeue() 3. MaxEle() 请设计一种数据结构和算法, 让 MAXELE 操作的时间复杂度尽可能的低 思路 1 ...
- 指针与C++基本原理
面向对象编程与传统的过程性编程的区别在于,OOP强调的是在运行阶段(而不是编译阶段)进行决策.运行阶段指的是程序正在运行时,编译阶段指的是编译器将程序组合起来时.运行阶段决策就好比度假时,选择参观那些 ...
- 创建4个线程,两个对j加一,两个对j减一(j两同两内)
package multithread; public class MyThread { //j变量私有 private int j; //同步的+1方法 private synchronized v ...
- 1854: [Scoi2010]游戏[并查集]
1854: [Scoi2010]游戏 Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 4938 Solved: 1948[Submit][Status] ...
- eclipse 的代码着色插件 --Eclipse Color Theme
Eclipse Color ThemeEclipse自带的背景颜色是白色的,很伤眼睛,故而安装一个颜色和主题插件,来改变代码区域的背景颜色以及关键字的颜色. 网址:http://eclipsecolo ...
- html 事件处理程序中的代码在执行时,有权访问全局作用域中的任何代码。
看一个简单的例子: html: <head> <meta charset="UTF-8"> <title>Document</title& ...
- [Gradle] 如何强制 Gradle 重新下载项目的依赖库
强制刷新 Gradle 依赖库缓存 $ gradle build --refresh-dependencies The --refresh-dependencies option tells Grad ...
- 160608、mysql距离函数st_distance
随着近几年各类移动终端的迅速普及,在手机移动定位app中,附近的人,附近的地点功能十分常见,基于地理位置的服务(LBS)和相关应用也越来越多,而支撑这些应用的最基础技术之一,就是基于地理位置信息的处理 ...
- 160513、nginx+tomcat集群+session共享(linux)
第一步:linux中多个tomcat安装和jdk安装(略) 第二步:nginx安装,linux中安装nginx和windows上有点不同也容易出错,需要编译,这里做介绍 一.安装依赖 gcc open ...