Fsm有限状态机深入浅析代码

Fsm适合用于:状态动画之间的跳转关系整理,降低耦合性,可扩展性增强。

直接进入正题。。。。

状态的抽象:三个状态

1,进入

2, 退出

3,循环

C层也就是控制层:

1,管理子状态

2,负责状态之间的交换

好的接下来上代码。。。。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public abstract class FsmBase : MonoBehaviour {
//进入
public abstract void OnEnter();
//退出
public abstract void OnLeave();
//循环
public abstract void Update();

}
//控制层
public class FsmManager
{
FsmBase[] allState;

sbyte stateIndex;//长度

sbyte curIndex;//当前处在某个状态下

//构造函数初始化
public FsmManager(sbyte stateCount)
{
allState = new FsmBase[stateCount];

stateIndex = -1;

curIndex = -1;
}

//添加状态
public void AddState(FsmBase state)
{

if (stateIndex<allState.Length)//做个范围限制
{
stateIndex++;

allState[stateIndex] = state;
}

}
//交换状态
public void ChangeState(sbyte stateNuber)
{
stateNuber = (sbyte)(stateNuber % allState.Length);//范围限制

if (curIndex!=-1)//表示有状态
{
allState[curIndex].OnLeave();//退出当前状态

curIndex = stateNuber;

allState[curIndex].OnEnter();//进入下一个状态
}
else
{
curIndex = stateNuber;

allState[curIndex].OnEnter();//进入
}
}

//循环
public void Upatate()
{
if (curIndex!=-1)
{
allState[curIndex].Update();
}
}
}

上面有两个类抽象类和管理

抽象里面有三个字段状态;

管理类里面具体实现这三个的

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using UnityEngine.Events;
//状态的类 类里面适合处理每个动画状态的类
public class IdleAnimator : FsmBase
{
Animator animator;

private float timeCount;//处理动画的

UnityAction<sbyte> callBack;//回调

public IdleAnimator(Animator tempAnimal,UnityAction<sbyte> tempBack)
{
animator = tempAnimal;

callBack = tempBack;
}
//进入
public override void OnEnter()
{
animator.SetInteger("动画1", 1);
}
//退出
public override void OnLeave()
{

}
//循环
public override void Update()
{
//简单写个动画计时器 表示在这处理动画的问题
timeCount += Time.deltaTime;
if (timeCount>=1)
{
timeCount = 0;

//animator.SetInteger 不能直接在这跳转 应该是如下操作
//切换到idle模式状态 这里启用了一个代理
callBack((sbyte)OrcCtrl.AnimalState.Idle);
}
}
}
public class RunAnimator : FsmBase
{
Animator animator;

public RunAnimator(Animator tempAnimal)
{
animator = tempAnimal;
}
//进入
public override void OnEnter()
{
animator.SetInteger("动画2", 2);
}
//退出
public override void OnLeave()
{

}
//循环
public override void Update()
{

}
}
public class WalkAnimator : FsmBase
{
Animator animator;

public WalkAnimator(Animator tempAnimal)
{
animator = tempAnimal;
}
//进入
public override void OnEnter()
{
animator.SetInteger("动画3", 3);
}
//退出
public override void OnLeave()
{

}
//循环
public override void Update()
{

}
}
public class AttackAnimator : FsmBase
{
Animator animator;

public AttackAnimator(Animator tempAnimal)
{
animator = tempAnimal;
}
//进入
public override void OnEnter()
{
animator.SetInteger("动画4", 4);
}
//退出
public override void OnLeave()
{

}
//循环
public override void Update()
{

}
}

每一个动画状态做一个类

在每个动画的类里可以做这个动画的具体事件

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class OrcCtrl : MonoBehaviour {

FsmManager fsmMangager;

public enum AnimalState
{
Idle,
Run,
Walk,
Attack,
//可以在这扩展
MaxValue
}
//代理
public void ChangeState(sbyte stateIndex)
{
fsmMangager.ChangeState(stateIndex);
}

void Start () {

fsmMangager = new FsmManager((sbyte)AnimalState.MaxValue);//方便扩展

Animator tempanimator = transform.GetComponent<Animator>();
//添加动画操作 1,idle
IdleAnimator tempidleAnimator = new IdleAnimator(tempanimator,ChangeState);
fsmMangager.AddState(tempidleAnimator);
//2,Run
RunAnimator temprunAnimator = new RunAnimator(tempanimator);
fsmMangager.AddState(temprunAnimator);
//3,walk
WalkAnimator tempwalkAnimator = new WalkAnimator(tempanimator);
fsmMangager.AddState(tempwalkAnimator);
//4,Attack
AttackAnimator tempattackAnimator = new AttackAnimator(tempanimator);
fsmMangager.AddState(tempattackAnimator);

}

// Update is called once per frame
void Update () {

//动画在这的一系列操作
if (Input.GetKeyDown(KeyCode.A))
{
//交换状态
fsmMangager.ChangeState((sbyte)AnimalState.Run);
}
if (Input.GetKeyDown(KeyCode.B))
{
//交换状态
fsmMangager.ChangeState((sbyte)AnimalState.Attack);
}
fsmMangager.Upatate();
}
}

这里主要是添加动画状态 脚本挂载需要的物体上

类似这个 然后Event用int idle是1

(老三标签,新手,如有错误请前辈指点一下)

原文地址:https://www.cnblogs.com/-831/p/12312040.html

时间: 2024-10-10 15:12:27

Fsm有限状态机深入浅析代码的相关文章

U3D架构系列之- FSM有限状态机设计六(总结篇)

由于最近一直赶项目进度,没时间写,昨晚终于项目终于完成了,空闲下来,做一个总结.在这一篇中主要是把前五章一起总结一下,以及通过举例演示如何使用?有限状态机在游戏中使用的地方非常多,比如我们界面之间的切换,角色的状态切换等等.所以非常值得大家去学习一下,接下来我们主要实现的功能,为了表达清楚,我通过图例给大家说明一下: 给大家解析一下,程序运行首先进入主菜单,里面有三个按钮,开始游戏,音量,退出游戏.先从第一个说起,如果是开始游戏,它会进入到下一个界面游戏界面,游戏界面有个返回主菜单功能.二者可以

U3D架构系列之- FSM有限状态机设计四

接下来,我们继续我们的FSM有限状态机的设计,在设计三中我们实现了FSState这个类,我们继续实现FSEvent事件处理类.在FSEvent类里面我们声明了FiniteStateMachine里面定义的委托函数.代码如下: protected FiniteStateMachine.EnterState mEnterDelegate; protected FiniteStateMachine.PushState mPushDelegate; protected FiniteStateMachin

U3d架构系列之-FSM有限状态机设计一

我们在游戏开发中经常面临架构设计问题,在蛮牛问答里面也有好多朋友问关于架构方面的问题,在这里我就将一些经常使用的游戏开发方面的知识跟大家介绍 一下, 一是给大家提供一个设计思路,在此基础上可以举一反三,二是大家可以通过这个平台共同学习.闲话不多说了,切入正题,FSM有限状态机,在游戏开发中如何使用?那些模块的设计需要它?接下来我们就分析一下游戏: 比如我们的玩家自身的状态切换,Idle,walk,attack等等,这些都属于状态的切换,可以用有限状态机:还有比如玩家去完任务:领取任务,杀怪,交易

Unity FSM 有限状态机

翻译了一下unity wiki上对于有限状态机的案例,等有空时在详细写一下.在场景中添加两个游戏物体,一个为玩家并修改其Tag为Player,另一个为NPC为其添加NPCControl脚本,并为其将玩家角色和路径添加上去.(该案例利用状态机简单的实现了一个NPC的简单AI---巡逻---看到玩家----追逐玩家----丢失玩家----巡逻) 效果: 状态机: 1 using System; 2 using System.Collections; 3 using System.Collection

FSM有限状态机的实现

参考原地址:http://www.manew.com/thread-48266-1-1.html 在查看了这么多状态机的文章后,终于找到个看懂的了,在此很感谢那位作者.果然还是要把代码下载下来慢慢分析才知道. 普通的AI逻辑都很简单,都是switch/case这样的形式,这个形式跟简单工厂模式非常类似,然而我们的工作是把模式改为工厂模式,即把那些case改为单独的状态类. 先从最简单的状态类来说明,先来一个状态抽象基类:FSMState.所有的状态类都继承自这个基类,比如巡逻类.攻击类.作为所有

U3D架构系列之- FSM有限状态机设计三

在设计二中,我们实现了有限状态机管理类,接下来,我们实现FSState这个类,这里类主要是状态的基本操作以及事件触发.在这里我们定义了在FiniteStateMachine类里声明的三个委托.在FSState里面使用的代码如下: protected FiniteStateMachine.EnterState mEnterDelegate; protected FiniteStateMachine.PushState mPushDelegate; protected FiniteStateMach

U3D架构系列之- FSM有限状态机设计五

在设计五中,我们把事件系统EventSystem实现一下.这个EventSystem类主要实现的是事件的注册,触发,以及分发Event消息的作用.提供接口对外使用的.在这里面为了功能扩展方便用了好多模板函数,方便大家调用. 分发消息的时候,我们采用的是队列的方式,就是先进先出原则. 首先要把消息事件注册一下,就是将其放到我们预先定义的表里面.函数代码如下所示: int Register(string eventName, Func<object,object,object,bool> acti

go - FSM(有限状态机)初体验

FSM有限状态机 /** * @Author: wsp * @Time : 2018/4/11 16:45 * @Description: */ package fsmStrudy import ( "fmt" "github.com/looplab/fsm" ) type Door struct { To string FSM *fsm.FSM } func NewDoor(to string) *Door { d := &Door{ To: to, }

Unity3D 利用FSM设计相机跟随实现

笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D实战核心技术详解>电子工业出版社等. CSDN视频网址:http://edu.csdn.net/lecturer/144 FSM有限状态机前面已经跟读者介绍过,使用Unity3D引擎实现了动作状态以及技能切换,FSM使用的条件是有限个状态切换,我们可以将FSM应用到相机中,很多人会问在相机中如何使用FS