首页 > 其他分享 >制作角色AI必用?!速通有限状态机

制作角色AI必用?!速通有限状态机

时间:2024-09-21 20:48:47浏览次数:8  
标签:必用 AI blackboard void FSM transform 状态机 public currentState

欢迎加入光光的奇妙冒险,我是你们的煎饼光子老师。

这期我们来速通一套有限状态机框架

我认为一个有限状态机必须要满足这三个条件

如果结合代码说就是

1.枚举表示的状态类型

2.当前处于的状态

3.通过Switch等逻辑去切换状态

首先我们创建一个FSM,也就是我们的有限状态框架

在代码中我已经给出了详细的注释

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

//状态类型用枚举表示
public enum E_StateType
{
    Idle,Walk
}

//状态接口
public interface IState
{
    void OnEnter();
    void OnUpdate();
    void OnExit();
    // void OnFixedUpdate();
    // void OnCheck(); 
}

[System.Serializable]
public class Blackboard
{
    //此处存储共享数据,或向外展示的数据,可配置的数据
}
public class FSM
{
    public IState currentState;//当前状态
    public Dictionary<E_StateType, IState> stateDic;//状态字典
    public Blackboard blackboard;//共享信息的黑板
    public FSM(Blackboard blackboard)
    {
        stateDic = new ();
        this.blackboard = blackboard;
    }

    /// <summary>
    /// 切换状态
    /// </summary>
    /// <param name="stateType"></param>
    public void SwitchState(E_StateType stateType)
    {
        if(!stateDic.ContainsKey(stateType))
        {
            return;
        }
        else
        {
            //如果当前状态不为空,则调用OnExit
            if(currentState!=null)
                currentState.OnExit();
            currentState=stateDic[stateType];
            currentState.OnEnter();
        }
    }

    /// <summary>
    /// 添加状态
    /// </summary>
    /// <param name="stateType"></param>
    /// <param name="state"></param>
    public void AddState(E_StateType stateType, IState state)
    {
        if(!stateDic.ContainsKey(stateType))
        {
            stateDic.Add(stateType, state);
        }
    }

    public void OnUpdate()
    {
        currentState.OnUpdate();
    }

    // public void OnFixedUpdate()
    // {
    //     currentState.OnFixedUpdate();
    // }

    // public void OnCheck()
    // {
    //     currentState.OnCheck();
    // }
}

接着我们来实际使用一下这个有限状态机框架 

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

//为某个对象专门创建一个黑板
[System.Serializable]
public class MyBlackboard:Blackboard
{
    public Animator anim;
    public Transform transform;//在外面关联某个对象的Transform
    public Vector2 targetPos;
    public float idleTime;
    public float moveSpeed;
}
public class IdleState : IState
{
    private float idleTimer;
    private FSM fsm;
    private MyBlackboard blackboard;

    //构造函数
    public IdleState(FSM fSM)
    {
        this.fsm = fSM;
        this.blackboard = fSM.blackboard as MyBlackboard;
    }
    
    public void OnEnter()
    {
        idleTimer = 0;
        blackboard.anim.Play("Idle");
    }

    public void OnExit()
    {
        
    }

    public void OnUpdate()
    {
        idleTimer += Time.deltaTime;
        if(idleTimer > blackboard.idleTime)
        {
            fsm.SwitchState(E_StateType.Walk);
        }
    }
}
public class WalkState : IState
{    
    private FSM fsm;
    private MyBlackboard blackboard;    

    //构造函数
    public WalkState(FSM fSM)
    {
        this.fsm = fSM;
        this.blackboard = fSM.blackboard as MyBlackboard;
    }
    public void OnEnter()
    {
        float randomX=Random.Range(-5,5);        
        blackboard.targetPos = new Vector2(blackboard.transform.position.x+randomX,blackboard.transform.position.y);
        blackboard.anim.Play("Walk");
    }

    public void OnExit()
    {
        
    }

    public void OnUpdate()
    {
        if(Vector2.Distance(blackboard.transform.position,blackboard.targetPos)<0.1f)
        {
            fsm.SwitchState(E_StateType.Idle);
        }
        else
        {
            blackboard.transform.position=Vector2.MoveTowards(blackboard.transform.position,blackboard.targetPos,Time.deltaTime*blackboard.moveSpeed);
        }
    }
}

public class MyAI : MonoBehaviour
{
    private FSM fsm;
    public MyBlackboard blackboard;
    void Start()
    {        
        fsm = new FSM(blackboard);
        fsm.AddState(E_StateType.Idle, new IdleState(fsm));
        fsm.AddState(E_StateType.Walk, new WalkState(fsm));
        fsm.SwitchState(E_StateType.Idle);               
    }
    private void Update() 
    {
        fsm.OnUpdate();
        Flip();
    }
    void Flip()
    {
        if(blackboard.targetPos!=Vector2.zero)
        {
            if(blackboard.targetPos.x>blackboard.transform.position.x)
            {
                transform.localScale=new Vector2(1,1);
            }
            else
            {
                transform.localScale=new Vector2(-1,1);
            }
        }
    }    
}

 

 

标签:必用,AI,blackboard,void,FSM,transform,状态机,public,currentState
From: https://blog.csdn.net/Blueberry124/article/details/142423891

相关文章

  • 智能写作新体验:AI写作小助手助力内容创作
    在信息时代的浪潮中,内容创作已成为连接世界、传递价值的重要桥梁。然而,传统的写作方式在效率和质量上往往难以满足现代社会的需求。此时,AI写作小助手的诞生,为内容创作带来了全新的体验。本文将深入探讨AI写作小助手如何助力内容创作,开启智能写作的新篇章。AI写作小助手:开......
  • 一文了解AI写作小助手,让创意无限放大
     在创作的海洋中,每一位作者都是一艘探索未知的小船,而AI写作小助手,便是那助推船只驶向深蓝的劲风。在这个信息爆炸、创意为王的时代,我们不仅要追求写作的速度与效率,更要让创意无限放大。本文将带你深入了解AI写作小助手,探讨它是如何成为创作者们放大创意的得力工具。 AI写作小......
  • Java笔试面试题AI答之单元测试JUnit(7)
    文章目录37.请列举一些JUnit扩展?1.参数化测试2.条件测试执行3.临时目录4.时间测试5.重复测试6.前置/后置条件7.Mockito8.SpringTest9.JUnitVintage10.Testcontainers11.自定义注解和扩展12.测试监听器(TestListener和RunListener)38.请列举Java程序员......
  • 基于 Qwen2.5-Coder 模型和 CrewAI 多智能体框架,实现智能编程系统的实战教程
    9月19日,阿里开源了Qwen2.5系列大模型全家桶:除常规的语言模型Qwen2.5之外,还发布了专门针对编程的Qwen2.5-Coder模型和数学的Qwen2.5-Math模型,并且针对每个模型都提供了不同规模参数版本,包括:Qwen2.5语音模型:0.5B,1.5B,3B,7B,14B,32B和72BQwen2.5-Coder编程模......
  • AI论文写作PPT思维导图PC小程序开发
    AI论文写作PPT思维导图PC小程序开发AI智能PPT功能一键生成PPT大纲、一键扩写大纲内容、单独扩写某个大纲内容、一键生成内容关键词、单项内容关键词生成、新增大纲项、修改大纲、删除大纲、选择PPT模板、单页模板一键切换、在线编辑模板;支持导出PPTX、JPEG、;PNG、JSON、PDF格式文件......
  • AI绘画实操 Stable Diffusion 到底怎么玩儿,新手必看的AI绘画入门安装使用教程
    大家好,我是灵魂画师向阳2024年,是AI绘画技术飞速发展的一年,各种AI绘画工具层出不穷,为了让大家在了解和学习AI绘画的过程中少走弯路,今天我将详细介绍目前世界上使用用户最多,社区最大,生态最丰富的免费图像生成模型——StableDiffusion,并为你提供详细的安装教程,让你轻松踏入AI......
  • AI绘画Flux【lora模型】【微缩景观】:惊艳!3D场景融入手机上的微景观!
    大家好,我是灵魂画师向阳今天和大家分享一款基于Flux底模训练的微缩景观模型——FLUX|手机上的微景观。此模型主要将手机作为微型景观的基底,强制将3d情景融入手机并控制在手机屏幕上方范围内。作者在使用提示词直出和使用该Loar+提示词生成的图片进行了对比。下面左侧图为......
  • AI跟踪报道第57期-新加坡内哥谈技术-本周AI新闻: 详谈GPT-o1模型和微软Copilot升级
      每周跟踪AI热点新闻动向和震撼发展想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领域的领跑者。点击订阅,与未来同行!订阅:https://......
  • EI, Scopus国际会议论文征稿:2024年第五届医学人工智能国际学术会议(ISAIMS 2024)
    连续四届EI检索|稳定ACM出版、EI检索|线上线下结合2024年第五届医学人工智能国际学术会议(ISAIMS2024)20245th InternationalSymposiumonArtificialIntelligenceforMedicalSciences大会官网:www.isaims.org 【论文投稿】武汉分会场大会时间:2024年10月25-27日......
  • Nodemailer 概述:在 Nodejs 中轻松发送电子邮件
    nodemailer是一个用于发送电子邮件的node.js模块。这是一个快速概述:transporter:定义电子邮件的发送方式(通过gmail、自定义smtp等)。consttransporter=nodemailer.createtransport({...});登录后复制消息对象:指定电子邮件详细信息,如发件人、收件人、主题和内容(文本/ht......