IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity有限自动机学习二 -> 正文阅读

[游戏开发]Unity有限自动机学习二

b站学习视频链接
代码进度截止至该链接的p3

一、Common

1.FSMStateID

namespace AI.FSM
{
    /// <summary>
    /// 条件编号
    /// </summary>
    public enum FSMStateID
    {
        /// <summary>
        /// 不存在该状态
        /// </summary>
        None,
        /// <summary>
        /// 默认
        /// </summary>
        Default,
        /// <summary>
        /// 死亡
        /// </summary>
        Dead,
        /// <summary>
        /// 闲置
        /// </summary>
        Idle,
        /// <summary>
        /// 追逐
        /// </summary>
        Pursuit,
        /// <summary>
        /// 攻击
        /// </summary>
        Attacking,
        /// <summary>
        /// 巡逻
        /// </summary>
        Patrolling
    }
}

2.FSMTriggerID

namespace AI.FSM
{
    /// <summary>
    /// 条件编号
    /// </summary>
    public enum FSMTriggerID
    {
        /// <summary>
        /// 没有生命
        /// </summary>
        NoHealth,
        /// <summary>
        /// 发现目标
        /// </summary>
        SawTarget,
        /// <summary>
        /// 到达目标
        /// </summary>
        ReachTarget,
        /// <summary>
        /// 目标被击杀
        /// </summary>
        KilledTarget,
        /// <summary>
        /// 超出攻击范围
        /// </summary>
        WithoutAttackRange,
        /// <summary>
        /// 丢失目标
        /// </summary>
        LoseTarget,
        /// <summary>
        /// 完成巡逻
        /// </summary>
        CompletePatrol
    }
}

二、States

1.DeadState

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

namespace AI.FSM
{
    /// <summary>
    /// 死亡状态
    /// </summary>
    public class DeadState : FSMState
    {
        public override void Init()
        {
            StateID = FSMStateID.Dead;
        }

        public override void EnterState(FSMBase fsm)
        {
            base.EnterState(fsm);
            //禁用状态机
            fsm.enabled = false;
        }

    }
}

2.IdleState

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

namespace AI.FSM {
    /// <summary>
    /// 待机
    /// </summary>
    public class IdleState : FSMState
    {
        public override void Init()
        {
            StateID = FSMStateID.Idle;
        }

        public override void EnterState(FSMBase fsm)
        {
            base.EnterState(fsm);
            //播放待机动画
            //fsm.anim.SetBool(fsm.chStatus.chParams.death,true);
        }

        public override void ExitState(FSMBase fsm)
        {
            base.ExitState(fsm);
            //取消待机动画
            //fsm.anim.SetBool(fsm.chStatus.chParams.death, false);
        }
    }
}

三、Triggers

1.NoHealthTrigger

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

namespace AI.FSM
{
    /// <summary>
    /// 条件:没有生命
    /// </summary>
    public class NoHealthTrigger : FSMTrigger
    {
        public override bool HandleTrigger(FSMBase fsm)
        {
            return fsm.chStatus.HP <= 0;
        }

        public override void Init()
        {
            TriggerID = FSMTriggerID.NoHealth;
        }
    }
}

四、CharacterAnimationParameter

namespace ARPGDemo.Character
{
    [System.Serializable]  //可以序列化
    public class CharacterAnimationParameter
    {
        public string run = "run";
        public string death = "death";
        public string idle = "idle";
    }
}

五、CharacterStatus

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

namespace ARPGDemo.Character
{
    /// <summary>
    /// 角色状态类
    /// </summary>
    public class CharacterStatus : MonoBehaviour
    {
        [Tooltip("动画参数")]
        public CharacterAnimationParameter chParams;

        [Tooltip("血量")]
        public float HP;
        [Tooltip("最大血量")]
        public float maxHP;
        [Tooltip("法力")]
        public float SP;
        [Tooltip("最大法力")]
        public float maxSP;
        [Tooltip("基础攻击力")]
        public float baseATK;
        [Tooltip("防御力")]
        public float defence;
        [Tooltip("攻击间隔")]
        public float attackInterval;
        [Tooltip("攻击距离")]
        public float attackDistance;

        public void Damage(float val) //10
        {
            val -= defence; //10-20
            if (val <= 0) return;
            HP -= val;//100 - -10
            if (HP <= 0) Death();
        }

        public void Death()
        {
            GetComponent<Animator>().SetBool(chParams.death,true);
            print("游戏结束");
        }

    }
}

六、FSMBase

using System.Collections;
using ARPGDemo.Character;
using System.Collections.Generic;
using UnityEngine;

namespace AI.FSM
{
    /// <summary>
    /// 状态机
    /// </summary>
    public class FSMBase : MonoBehaviour
    {
        #region Unity生命周期
        private void Start()
        {
            InitComponent();
            ConfigFSM();
            InitDefaultState();
        }

        //每帧的处理
        public void Update()
        {
            //判断当前状态条件...
            currentState.Reason(this);
            //执行当前状态逻辑
            currentState.ActionState(this);
        }
        #endregion

        #region 状态机自身成员
        //状态列表
        private List<FSMState> states;
        [Tooltip("默认状态编号")]
        public FSMStateID defaultStateID;
        //默认状态
        private FSMState defaultState;
        //当前状态
        public FSMState currentState;

        private void InitDefaultState() {
            //查找默认状态
            defaultState = states.Find(s => s.StateID == defaultStateID);
            //为当前状态赋值
            currentState = defaultState;
            //进入状态
            currentState.EnterState(this);
        }

        //配置状态机
        private void ConfigFSM() {
            states = new List<FSMState>();
            //-- 创建状态对象
            IdleState idle = new IdleState();
            //-- 添加映射(AddMap)
            idle.AddMap(FSMTriggerID.NoHealth,FSMStateID.Dead);
            //-- 加入状态机
            states.Add(idle);

            DeadState dead = new DeadState();
            states.Add(dead);
        }

        //切换状态
        public void ChangeActiveState(FSMStateID stateID) {
            //FSMStateID.Default
            //如果需要切换的状态编号是:Default,则直接返回默认状态;
            //否则从状态列表中查找
            //if (stateID == FSMStateID.Default)
            //    currentState = defaultState;
            //else
            //    currentState = states.Find(s => s.StateID == stateID);

            //离开上一个状态
            currentState.ExitState(this);
            //切换状态
            currentState = stateID == FSMStateID.Default ? currentState = defaultState: states.Find(s => s.StateID == stateID);
            //进入下一个状态
            currentState.EnterState(this);
        }
        #endregion

        #region 为状态与条件提供的成员
        [HideInInspector]
        public Animator anim;
        [HideInInspector]
        public CharacterStatus chStatus;

        public void InitComponent()
        {
            anim = GetComponentInChildren<Animator>();
            chStatus = GetComponent<CharacterStatus>();
        }
        #endregion

        /*
         主要执行流程:
         状态机每帧检测当前状态的条件 ---> 状态类遍历所有条件对象 --->
         如果某个条件达成 ---> 状态机切换当前状态
         */
    }
}

七、FSMState

using System;
using System.Collections.Generic;

namespace AI.FSM
{
    public abstract class FSMState
    {
        //编号
        public FSMStateID StateID { get; set; }

        //映射表
        private Dictionary<FSMTriggerID, FSMStateID> map;

        //条件列表
        private List<FSMTrigger> Triggers;

        public FSMState() {
            map = new Dictionary<FSMTriggerID, FSMStateID>();
            Triggers = new List<FSMTrigger>();

            Init();
        }

        //检测当前状态的条件是否满足
        public void Reason(FSMBase fsm)
        {
            for(int i = 0; i < Triggers.Count; i++)
            {
                //发现条件满足
                if (Triggers[i].HandleTrigger(fsm))
                {
                    //从映射表中获取输出状态
                    FSMStateID stateID = map[Triggers[i].TriggerID];
                    //切换状态
                    fsm.ChangeActiveState(stateID);
                    return;
                }
            }
        }

        //要求实现类必须初始化状态类,为编号赋值
        public abstract void Init();

        //由状态机调用(为映射表和条件列表赋值)
        public void AddMap(FSMTriggerID triggerID,FSMStateID stateID) {
            //添加映射
            map.Add(triggerID, stateID);
            //创建条件对象
            CreateTrigger(triggerID);
        }

        private void CreateTrigger(FSMTriggerID triggerID) {
            //创建条件对象
            //命名规范:AI.FSM. + 条件枚举 + Trigger
            Type type = Type.GetType("AI.FSM." + triggerID + "Trigger");
            FSMTrigger trigger = Activator.CreateInstance(type) as FSMTrigger;
            Triggers.Add(trigger);
        }

        //为具体状态类提供可选实现
        public virtual void EnterState(FSMBase fsm) { }
        public virtual void ActionState(FSMBase fsm) { }
        public virtual void ExitState(FSMBase fsm) { }

    }
}

八、FSMTrigger

using AI.FSM;
/// <summary>
/// 条件类
/// </summary>
public abstract class FSMTrigger
{
    //编号
    public FSMTriggerID TriggerID { get; set; }

    public FSMTrigger() {
        Init();
    }

    //要求子类必须初始化条件,为编号赋值
    public abstract void Init();

    //逻辑处理
    public abstract bool HandleTrigger(FSMBase fsm);
}

代码下载链接

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-08-04 11:32:18  更:2021-08-04 11:33:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/6 17:36:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码