Unity有限状态机编写

有限状态机FSM

是对行为逻辑的抽象。

在整个FSM架构中

首先有一个状态基类stateObject

里面有三个方法,分别是状态前、状态中、状态后。

所有具体行为类都要继承这个基类,在这三个方法中具体实现各种方法的逻辑。

然后,需要一个stateManager(大脑)状态管理类来管理这些状态,特别注意的是里面changeState方法,他是状态跳转的关键。

至于如果存储各种状态,你可以用list类 ,字典类等等。

写法:

建类:确认一共有几个状态,新建对应的几个类,还有他的Manager(管理类)和父类State

代码:

1.在父类中先public一个管理类类型的变量,为的是让每个状态对应一个状态管理者。然后写状态前,状态中,状态后三个方法。注意这三个方法的类型为virtual,方便子类进行重写。

因为状态前后都只执行一次,所以返回值为void。状态中的返回值类型为该类类型,可以先返回空值。

2.让所有状态类继承该父类,并对里面的方法进行重写。在三个方法中添加自己的行为逻辑。注意在状态中的return中返回this(当前状态自身)

3.写管理类(重点):

1)首先管理类也要继承该父类。可以做成状态字典,存储对象的所有状态,只有在这个状态字典中才可以转换调用。注意,如果要使用字典必须using System.Collection.Generic。字典写法:Dictionary<string, State> stateDic;

String用来传状态名称,State为当前状态所有对象。然后定义当前状态:State currentState;

和上一个状态:State lastState;

2)在构造器中进行初始化stateDic = new Dictionary<string, State>();

using UnityEngine;

using System.Collections;

using System.Collections.Generic;

public class StateManager : State

{

//状态管理类 用字典,是功能类

//状态字典,存储对象的所有状态,只有在这个状态字典中才可以转换调用

Dictionary<string, State> stateDic;

//当前状态

State currentState;

//上一个状态

State lastState;

//初始化放在构造器中

public StateManager()

{

stateDic = new Dictionary<string, State>();

}

//注册状态,需要状态名字和状态参数的形参

public void RegisterState(string stateName, State state)

{

//每一次注册一个状态时,就指定这个状态的状态管理者的字段对应注册的这个对象

//this指代当前类对象实例Dictionary<string, State>(),谁.RegisterState就是谁

//作用是让一个对象的多个状态都指向同一个管理者

state.stateManager = this;

//向状态字典中添加,传递形参状态

stateDic.Add(stateName, state);

}

//设置默认状态,传递状态名为形参

public void SetDefaultState(string stateName)

{

//判断方法列表是否包含这样的一个状态(key值)

if (!stateDic.ContainsKey(stateName))

{

Debug.LogError("状态列表无此状态");

}

//设置默认状态

currentState = stateDic[stateName];

}

//改变状态

public void ChangeState(string stateName)

{

//判断方法列表是否包含这样的一个状态(key值)

//改变状态失败

if (!stateDic.ContainsKey(stateName))

{

Debug.LogError("状态列表无此状态,切换失败");

currentState = lastState;

}

//切换成功,更改状态

currentState = stateDic[stateName];

}

//状态的执行

public void DoState()

{

//第一次执行的时候current是设置的默认状态,lastState是空

if (currentState != lastState)//加入默认状态为sleep//current=sleep;last=null //第2轮.current=eat;last=sleep

{

currentState.EnterState();//sleep的进入方法,只执行一次//current=sleep;last=null

//把后一个状态赋给当前状态,跳出if条件

lastState = currentState;//current=sleep;last=sleep

}

//执行“状态中”

lastState.StayState();//sleep的持续方法 //current=sleep;last=sleep

//退出状态                                  //sleep切换为eat//current=eat;last=sleep

if (lastState != currentState)//current=eat;last=sleep

{

lastState.ExitState();          //sleep退出

}

}

}

然后新建一个挂在游戏物体上的类

using UnityEngine;

using System.Collections;

public class FSMManager_Boss : MonoBehaviour {

StateManager_Boss manager;

// Use this for initialization

void Start () {

manager = new StateManager_Boss();

// 注册状态

manager.RegisterState("idle", new IdleState_Boss());

manager.RegisterState("run", new RunState_Boss());

manager.RegisterState("attack", new AttackState_Boss());

manager.RegisterState("Death", new DeathState_Boss());

//设置初始状态

manager.SetDefaultState("idle");

}

// Update is called once per frame

void Update () {

manager.DoState();

}

}

时间: 2024-08-07 08:21:30

Unity有限状态机编写的相关文章

(五)Unity5.0新特性------unity中编写脚本

?? 出处:http://blog.csdn.net/u010019717 author:孙广东      时间:2015.3.32 之前的Unity脚本 我们利用Mono(WinRT 在Windows Store Apps 和Windows Phone上) 使用 C# ,获得第三方库和接近本机性能的易用性.然而,有一些挑战: C# 运行时性能仍然落后于 C/c + + 最新和最好的.NET 语言和运行时功能在Unity's current version of Mono并不支持. 大约 23

Unity使用DLL库

Unity3D 能够很方便的集成一些外部插件,以便调用现有的动态链接库.下面会介绍Unity中如何集成Dll的两种方法.1. 标准引用这里所使用的语言是C#. 1.1 新建C#类库项目,这里就不多介绍了. 1.2 项目建好后正常的编写代码 以上是一个简单的测试代码. 1.3 将项目属性 -> 应用程序 -> 目标框架:改为 .NET Framework 3.5或以下 .这一步很重要,因为Unity3D(当前的Unity3D版本是3.5版) 支持的 .Net 是3.5版. 如果选择的是4.0版会

Unity 网络通信(一)Unity Network 初步

翻了半天unity的API,也没有发现可以处理Socket的方法.Unity自己封了个网络处理的类Network,主要用于状态同步. 似乎是要实现MMO级别的网络应用,只能用C#自己去写了.(Unity不像AS,有直接处理数据包.字节级别的底层函数.至少现在没有.) 我们还是先了解一下Unity,看看用Unity如何编写通信,从最简单的开始. 1,新建项目.新建一个项目里面会有一个摄像机. 2,编写服务器端代码cs: using UnityEngine; using System.Collect

《Unity Shader 与 计算机图形学》第二章

提示:本篇将会非常长~ 本系列文章分为 硬件 编程入门 工程实践 上一篇 主要介绍了GPU的特征工作原理 以及渲染的底层流程 其实对于新架构而言还有所不同 Shader描述了如何渲染物体的信息,包括: Texture Setup.纹理设置 Material Property.材质设置 Render State.渲染状态 Blend Setup.混合设置 Pixel Shader.像素着色 Vertex Shader.定点着色 Render Target Setup 渲染目标设置 Shader并不

Android与Unity交互研究

Android与Unity交互研究 转载请注明出处:http://blog.csdn.net/crazy1235/article/details/46733221 Android与Unity交互研究 unity与android交互的由来 unity简单介绍 unity与android交互介绍 unity调用android的方法 android调用untiy的方法 unity与android交互的由来 本人在项目开发过程中,遇到这样一个需求,把unity的场景放到android中去显示.刚开始做的

C#开发Unity游戏教程之Unity中方法的参数

C#开发Unity游戏教程之Unity中方法的参数 Unity的方法的参数 出现在脚本中的方法,无论是在定义的时候,还是使用的时候,后面都跟着一对括号“( )”,有意义吗?看起来最多也就是起个快速识别方法的作用吧.既然C#的语法规定方法就应该这么写,肯定是有一定道理的.如果是上升到战略意义的道理,连作者也不是很明白,但是作者知道这对括号里可以添加“参数”. Unity中参数的作用 要说明参数的作用,就必须从方法说起.方法可以处理变量中的数据,进而影响游戏对象的行为逻辑,这是本章前面一直在强调的.

【Unity与23种设计模式】解释器模式(Interpreter)

GoF中定义: "定义一个程序设计语言所需要的语句,并提供解释来解析(执行)该语言." 传统上,执行程序代码通常通过两种方式 第一种:编译程序 第二种:解释器 常见的使用解释器的程序设计语言 包含流行与网页设计领域中的脚本语言 如JavaScript.PHP.Ruby等 这些程序代码经过一般文本编辑器编写完成后放入指定的位置 就可以由应用程序中的解释器直接执行 包括Lua Unity中 编写好的脚本程序执行之前会被UnityEngine编译过 严格来说不算是解释器模式 但与十几年前的开

Unity 通过脚本修改源资源

自动实例化 如果要修改任何游戏资源,通常希望在运行时修改,且修改是暂时的.例如,如果角色获得了无敌状态,可能想更改材质 (material) 的着色器 (shader),以便玩家角色形象地展示无敌的状态.该操作包含修改正在使用的材质.这种修改不是永久性的,因为我们不希望退出播放模式 (Play Mode) 时材质的着色器不同. 但是,在 Unity 中编写脚本永久修改源资源是可行的.我们从上面的材质示例开始说起. 若要临时更改材质的着色器,可更改材质 (material) 组件中的着色器 (sh

Unity中Awake与Start函数的调用情况总结(转)

在Unity中编写脚本时,有一系列的可重写(override)函数供我们使用,其中的Awake与Start两个函数作为初始化与设置之用,几乎在每个脚本中都要用到.因此,正确的把握这两个函数的调用时机,就能让我们在程序开发过程中避免一些错误,提高开发效率.比较懒,所以就没有上图,欢迎大家的批评指正: ) 1.  Awake函数 首先,我们来看unity的参考手册中对Awake函数的一些说明情况: 当脚本实例被加载时会调用Awake函数:Awake函数在所有的游戏对象被初始化完毕之后才会被调用:在脚