unity 有限状态机使用

2024-06-09 14:48
文章标签 使用 unity 状态机 有限

本文主要是介绍unity 有限状态机使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

有限状态机,(英语:Finite-state machine, FSM),又称有限状态自动机,简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。状态存储关于过去的信息,它反映从系统开始到现在时刻输入的变化;转移指示状态变更,用必须满足来确使转移发生的条件来描述它;动作是在给定时刻要进行的活动描述。有多种类型的动作:
进入动作(entry action):在进入状态时进行;
退出动作:在退出状态时进行;
输入动作:依赖于当前状态和输入条件进行;
转移动作:在特定转移时进行。
游戏引擎是有限状态机最为成功的应用领域之一,由于设计良好的状态机能够被用来取代部分的人工智能算法,因此游戏中的每个角色或者器件都有可能内嵌一个状态机。考虑RPG游戏中城门这样一个简单的对象,它具有打开(Opened)、关闭(Closed)、上锁(Locked)、解锁(Unlocked)四种状态,如图1所示。当玩家到达一个处于状态Locked的门时,如果此时他已经找到了用来开门的钥匙,那么他就可以利用它将门的当前状态转变为Unlocked,进一步还可以通过旋转门上的把手将其状态转变为Opened,从而成功地进入城内。
在描述有限状态机时,状态、事件、转换和动作是经常会碰到的几个基本概念。
状态(State)指的是对象在其生命周期中的一种状况,处于某个特定状态中的对象必然会满足某些条件、执行某些动作或者是等待某些事件。
事件(Event)指的是在时间和空间上占有一定位置,并且对状态机来讲是有意义的那些事情。事件通常会引起状态的变迁,促使状态机从一种状态切换到另一种状态。
转换(Transition)指的是两个状态之间的一种关系,表明对象将在第一个状态中执行一定的动作,并将在某个事件发生同时某个特定条件满足时进入第二个状态。
动作(Action)指的是状态机中可以执行的那些原子操作,所谓原子操作指的是它们在运行的过程中不能被其他消息所中断,必须一直执行下去。
创建状态机的基类
“`
using UnityEngine;
using System.Collections;

public interface Istate {

uint GetStateId();//获取状态id
void EnterState(Istate preState);//进入状态
void LeaveState(Istate nextState);//离开状态
void OnUpdate();//更新状态
void OnFixedUpdate();//更新状态
void OnLateUpdate();//更新状态

}


创建状态管理类

using UnityEngine;
using System.Collections;

public class PatrolState : Istate
{
Transform player;
Transform enemy;
Transform[] paths;
Animator anim;
CharacterController cc;
int pathIndex = 0;
public PatrolState(Transform player, Transform enemy, Transform[] paths)
{
this.paths = paths;
this.player = player;
this.enemy = enemy;
anim = enemy.GetComponent();
cc = enemy.GetComponent();

}
public uint GetStateId()
{//获取状态idreturn (uint)EnemyStateId.PatrolState;
}public void EnterState(Istate preState)
{//设置动画为运动anim.SetBool("Idel", false);
}public void LeaveState(Istate nextState)
{}public void OnUpdate()
{//控制移动和移动方向enemy.LookAt(paths[pathIndex]);cc.SimpleMove(enemy.transform.forward * 3f);if (Vector3.Distance(enemy.position, paths[pathIndex].position) < 1){//当敌人与下一个节点距离小于1,转换节点pathIndex++;if (pathIndex >= paths.Length){pathIndex = 0;}}//当敌人与玩家距离小于15,切换为追击玩家状态if (Vector3.Distance(enemy.position, player.position) < 15){enemy.GetComponent<EnemyCtrl>().SwitchState((uint)EnemyStateId.ChaseState);}}public void OnFixedUpdate()
{}public void OnLateUpdate()
{}

}

“`
创建状态管理类

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class StateMachine
{Dictionary<uint, Istate> stateDic = new Dictionary<uint, Istate>();Istate currentState;uint currentStateId;public Istate CurrentState{//获取当前状态get { return currentState; }}public uint CurrentStateId{//获取当前状态idget { return currentState.GetStateId(); }}public void RegisterState(Istate state){//如果状态没有被注册过,注册状态if (state == null || stateDic.ContainsKey(state.GetStateId())){return;}stateDic.Add(state.GetStateId(), state);}//切换状态public void SwitchState(uint stateId){if (currentState != null && stateId == currentStateId){return;}Istate newState;Istate oldState;stateDic.TryGetValue(stateId, out newState);if (newState != null){if(currentState!=null){currentState.LeaveState(newState);}oldState = currentState;currentState = newState;currentState.EnterState(oldState);}}public void Update(){if (currentState!=null){currentState.OnUpdate();}}public void FixedUpdate(){if (currentState != null){currentState.OnFixedUpdate();}}public void LateUpdate(){if (currentState != null){currentState.OnLateUpdate();}}}

UI管理类

using UnityEngine;
using System.Collections;
public enum EnemyStateId : uint
{NullState = 0, PatrolState, ChaseState, AttackState
}
public class EnemyCtrl : AttackAndDamage
{public Transform player;public Transform[] paths;private StateMachine fsm;//初始化void Awake(){//初始化状态机fsm = new StateMachine();}void Start(){//注册状态RegisterState();}private void RegisterState(){//注册状态fsm.RegisterState(new PatrolState(player, this.transform, paths));fsm.RegisterState(new ChaseState(player, this.transform));fsm.RegisterState(new AttackState(player, this.transform,baseAttack));fsm.SwitchState((uint)EnemyStateId.PatrolState);}public void SwitchState(uint stateId) {//进行状态切换fsm.SwitchState(stateId);}// 更新数据void Update(){//进行状态更新fsm.Update();}void FixedUpdate(){fsm.FixedUpdate();}void LateUpdate(){fsm.LateUpdate();}}

这篇关于unity 有限状态机使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1045486

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

【北交大信息所AI-Max2】使用方法

BJTU信息所集群AI_MAX2使用方法 使用的前提是预约到相应的算力卡,拥有登录权限的账号密码,一般为导师组共用一个。 有浏览器、ssh工具就可以。 1.新建集群Terminal 浏览器登陆10.126.62.75 (如果是1集群把75改成66) 交互式开发 执行器选Terminal 密码随便设一个(需记住) 工作空间:私有数据、全部文件 加速器选GeForce_RTX_2080_Ti

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念