HFSM(HierarchyFiniteStateMachine)分层有限状态机 四

HFSM(HierarchyFiniteStateMachine)分层有限状态机 四
接上篇,讲解一下自定义状态节点如何添加到编辑器,以及如何让AI运行起来。

新建脚本
StateEat 吃饭状态 继承于 HSMStateBase
StateHomeWork 吃饭状态 继承于 HSMStateBase
StateNetWork 吃饭状态 继承于 HSMStateBase
StatePlayBasketBall 吃饭状态 继承于 HSMStateBase
StatePlayGame 吃饭状态 继承于 HSMStateBase
StateRead 吃饭状态 继承于 HSMStateBase
StateTakeReset 吃饭状态 继承于 HSMStateBase
StateWatchTV吃饭状态 继承于 HSMStateBase
各状态分别实现 void Enter() void Exit() void Execute()

然后在 ConfigBheaviorNode 脚本中添加自定义节点
在这里插入图片描述
编辑器中即可出现自定义的状态节点了
在这里插入图片描述
新建Human.cs 脚本,代码如下,代码中需要的地方有注释

using System.Collections;
using UnityEngine;
using HSMTree;
using GenPB;

public interface IHuman
{
    void SetHuman(Human human);
}

public class Human : MonoBehaviour
{
    // 层次状态机实例
    private HsmEntity hsmEntity;

    private float read = 0;        // 看书
    private float homework = 0;    // 写作业
    private float network = 0;     // 网上听课
    private float playGame = 0;    // 玩游戏
    private float watchTV = 0;     // 看电视
    private float basketball = 0;  // 打篮球
    private float senseHunger = 10;// 饥饿感
    private float energy = 0;      // 精力

    void Start()
    {
        // 加载配置文件
        StartCoroutine(HsmTreeData.Instance.LoadConfig());
        StartCoroutine(LoadConfigData());
    }

    void Update()
    {
        // 每帧执行层次状态机逻辑
        if (null != hsmEntity)
        {
            hsmEntity.Execute();
        }
    }

    // 加载配置文件
    private IEnumerator LoadConfigData()
    {
        yield return new WaitForSeconds(1);

        // 根据自己配置的 HSM 配置文件名 "Student" 加载数据 
        SkillHsmConfigHSMTreeData hsmConfigData = HsmTreeData.Instance.GetHsmInfo("Student");
        // 将读取到的 配置文件数据解析为 层次状态机类对象
        hsmEntity = new HsmEntity(hsmConfigData);

        // 遍历所有节点,将 Human 赋值给自定义的状态
        foreach (var kv in hsmEntity.HsmStateMachine.AllNode())
        {
            AbstractNode abstractNode = kv.Value;
            if (typeof(IHuman).IsAssignableFrom(abstractNode.GetType()))
            {
                IHuman iHuman = abstractNode as IHuman;
                // 将 Human 赋值给自定义的状态
                iHuman.SetHuman(this);
            }
        }
    }

    // 移动
    public bool MoveTo(PlaceEnum place)
    {
        Vector3 desirtPos = Place.Instance._placeDic[place];
        if (Vector3.Distance(transform.position, desirtPos) <= 0.5f)
        {
            return true;
        }

        transform.Translate((desirtPos - transform.position).normalized * Time.deltaTime * 5, Space.World);
        return false;
    }

    public void Read(float value)
    {
        read = Mathf.Clamp(read + value * Time.deltaTime, 0, 10);
        // 更新环境变量的值
        hsmEntity.ConditionCheck.SetParameter("read", read);
    }

    public void Homework(float value)
    {
        homework = Mathf.Clamp(homework + value * Time.deltaTime, 0, 10);
        // 更新环境变量的值
        hsmEntity.ConditionCheck.SetParameter("homework", homework);
    }

    public void NetWrok(float value)
    {
        network = Mathf.Clamp(network + value * Time.deltaTime, 0, 10);
        // 更新环境变量的值
        hsmEntity.ConditionCheck.SetParameter("network", network);
    }

    public void PlayGame(float value)
    {
        playGame = Mathf.Clamp(playGame + value * Time.deltaTime, 0, 10);
        // 更新环境变量的值
        hsmEntity.ConditionCheck.SetParameter("playGame", playGame);
    }

    public void WatchTV(float value)
    {
        watchTV = Mathf.Clamp(watchTV + value * Time.deltaTime, 0, 10);
        // 更新环境变量的值
        hsmEntity.ConditionCheck.SetParameter("watchTV", watchTV);
    }

    public void Basketball(float value)
    {
        basketball = Mathf.Clamp(basketball + value * Time.deltaTime, 0, 10);
        // 更新环境变量的值
        hsmEntity.ConditionCheck.SetParameter("basketball", basketball);
    }

    public void Hunger(float value)
    {
        senseHunger = Mathf.Clamp(senseHunger + value * Time.deltaTime, 0, 10);
        // 更新环境变量的值
        hsmEntity.ConditionCheck.SetParameter("senseHunger", senseHunger);
    }

    public void Enery(float value)
    {
        energy = Mathf.Clamp(energy + value * Time.deltaTime, 0, 10);
        // 更新环境变量的值
        hsmEntity.ConditionCheck.SetParameter("energy", energy);
    }
}

将 Human.cs 挂载到一个物体上运行即可

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值