Unity有限状态机简单实现

  • 简单框架实现

1、IState

using UnityEngine;



namespace FSMLearn

{

    public interface IState

    {

        void OnEnter();



        void OnUpdate();



        void OnExit();



    }

2、BaseFSM

using System.Collections.Generic;

using UnityEngine;



namespace FSMLearn

{

    public class BaseFSM : MonoBehaviour

    {

        public IState CurState;

        protected Dictionary<State_Enum, IState> states = new Dictionary<State_Enum, IState>();



        public virtual void Awake()

        {

            Init();

        }



        public virtual void Init()

        {



        }



        public virtual void Update()

        {

            if(CurState != null)

            {

                CurState.OnUpdate();

            }

        }



        public void TransitionState(State_Enum state)

        {

            if(CurState != null)

            {

                CurState.OnExit();

            }

            if(states.ContainsKey(state))

            {

                CurState = states[state];

                CurState.OnEnter();

            }

            else

            {

                Debug.LogError("states中没有该状态:" + state.ToString());

            }

        }



    }

}

3、State_Enum

// BaseFSM脚本



/// <summary>

/// 状态枚举类型

/// </summary>

public enum State_Enum

{

    //自己定义所有的状态枚举

}

  • 简单使用

  • 需要实现功能,敌人巡逻,玩家和敌人距离小于3米,敌人追逐玩家,距离大于5米时则继续巡逻

1、实现所有需要用到的状态类,并完成对应功能,Patrol ,Figh

public class Patrol : FSMLearn.IState

{

    public EnemyFSM baseFSM;

    public Transform[] patrolPos;



    private int curIndex = 0;



    public Patrol(Transform[] posArr, EnemyFSM baseFSM)

    {

        patrolPos = posArr;

        this.baseFSM = baseFSM;

    }



    void FSMLearn.IState.OnEnter()

    {

        //throw new System.NotImplementedException();

    }



    void FSMLearn.IState.OnExit()

    {

        //throw new System.NotImplementedException();

    }



    void FSMLearn.IState.OnUpdate()

    {

        //throw new System.NotImplementedException();

        if(Vector3.Distance(baseFSM.transform.position, patrolPos[curIndex].position) < 0.2f)

        {

            curIndex = (curIndex + 1) % patrolPos.Length;

            baseFSM.transform.LookAt(patrolPos[curIndex].position);

        }

        Vector3 dir = (patrolPos[curIndex].position - baseFSM.transform.position).normalized;



        baseFSM.transform.LookAt(patrolPos[curIndex].position);

        baseFSM.transform.position += dir * 3 * Time.deltaTime;

    }

}



public class Fight : FSMLearn.IState

{

    public EnemyFSM baseFSM;

    public Transform target;



    public Fight(EnemyFSM baseFSM)

    {

        this.baseFSM = baseFSM;

    }



    void FSMLearn.IState.OnEnter()

    {

        target = GameObject.FindWithTag("Player").transform;

        baseFSM.transform.LookAt(target.position);

    }



    void FSMLearn.IState.OnExit()

    {

        //throw new System.NotImplementedException();

    }



    void FSMLearn.IState.OnUpdate()

    {

        Vector3 dir = (target.position - baseFSM.transform.position).normalized;

        baseFSM.transform.LookAt(target.position);

        baseFSM.transform.position += dir * 3 * Time.deltaTime;

    }

}



2、定义状态类枚举,巡逻状态,追逐敌人状

// BaseFSM脚本



/// <summary>

/// 状态枚举类型

/// </summary>

public enum State_Enum

{

    巡逻状态,

    追逐敌人状态

}


3、继承BaseFSM,注册状态并在Update函数实现状态条件切换

using FSMLearn;

using System.Collections;

using System.Collections.Generic;

using UnityEditor;

using UnityEngine;



public class EnemyFSM : FSMLearn.BaseFSM

{

    public Transform[] patrolPosArr;

    public Transform player;



    public override void Init()

    {

        base.Init();

        states.Add(State_Enum.巡逻状态, new Patrol(patrolPosArr, this));

        states.Add(State_Enum.追逐敌人状态, new Fight(this));



        TransitionState(State_Enum.巡逻状态);

    }



    public override void Update()

    {

        base.Update();

        if(Vector3.Distance(player.position, transform.position) < 3)

        {

            TransitionState(State_Enum.追逐敌人状态);

        }



        if(Vector3.Distance(player.position, transform.position) > 5)

        {

            TransitionState(State_Enum.巡逻状态);

        }

    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值