Unity中使用FSM状态机处理AI敌人追击玩家的功能

11 篇文章 0 订阅
1 篇文章 0 订阅

实现的功能:AI在固定的路径上巡逻,当玩家靠近AI的视野范围时,AI会追击玩家。当玩家跑出AI的视野范围时,AI则会放弃追击继续回到原来的地方进行巡逻。

参考资料:http://wiki.unity3d.com/index.php/Finite_State_Machine.
效果:1
FSM基类:

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

//状态转化的条件枚举
public enum Transition
{
    DefualtNull=0,//空条件
    SeePlayer,//看向玩家
    LostPlayer,//放弃追击玩家
}
//当前状态的枚举
public enum StateID
{
    NullState=0,//空状态
    MonstersWay, //enemy巡逻状态
    ChasePlayer,//enemy追玩家
}

/// <summary>
/// FSM状态基类
/// </summary>
public abstract class FSMState 
{
    protected StateID _stateID;
    public StateID ID { get { return _stateID; } }
    //保存所有状态转化条件和状态的字典
    protected Dictionary<Transition, StateID> Map = new Dictionary<Transition, StateID>();
    //区分哪个状态机管理自身
    protected FSMControl _fsm;
    public FSMState(FSMControl fsm)
    {
        this._fsm = fsm;
    }

    //添加
    public void AddTransition(Transition _trans, StateID _state)
    {
        if (_trans==Transition.DefualtNull)
        {
            Debug.Log("状态转化条件为空!");
            return;
        }
        if (_state== StateID.NullState)
        {
            Debug.Log("状态为空!");
            return;
        }
        if (Map.ContainsKey(_trans))
        {
            Debug.Log("字典中已经存在了"+_state+"状态!");
            return;
        }
        Map.Add(_trans,_state);
    }
    //移除
    public void RemoveTransition(Transition _trans)
    {
        if (_trans == Transition.DefualtNull)
        {
            Debug.Log("状态转化条件为空!");
            return;
        }
        if (Map.ContainsKey(_trans))
        {
            Debug.Log("字典中不存在了" + _trans + "状态转化条件!");
            return;
        }
        Map.Remove(_trans);
    }
    //得到
    public StateID GetOutputState(Transition _trans)
    {
        //如果字典中不包含就返回空
        if (Map.ContainsKey(_trans))
        {
            return Map[_trans];
        }
        return StateID.NullState;
    }

    public virtual void DoBeforEnter() { } //状态进入
    public virtual void DoBeforLeaving() { }//状态离开
    public abstract void Reson(GameObject go);//状态过渡
    public abstract void Act(GameObject go);//当前状态

}

控制管理类:

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

public class FSMControl
{
    //保存所有的状态
    private Dictionary<StateID, FSMState> states = new Dictionary<StateID, FSMState>();
    //当前状态
    private StateID currentStateID;
    private FSMState currentFSM;

    public void UpdateState(GameObject go)
    {
        currentFSM.Act(go);
        currentFSM.Reson(go);
    }

    public void AddState(FSMState fsm)
    {
        if (fsm==null)
        {
            Debug.Log("传进来的fsm为空!");return;
        }
        if (currentFSM== null)
        {
            currentFSM = fsm;
            currentStateID = fsm.ID;
        }
        if (states.ContainsKey(fsm.ID))
        {
            Debug.Log("状态"+fsm.ID+"已经存在!");return;
        }
        states.Add(fsm.ID,fsm);
    }
    public void DeleteState(StateID id)
    {
        if (id==StateID.NullState)
        {
            Debug.Log("传进来的id为空!");return;
        }
        if (!states.ContainsKey(id))
        {
            Debug.Log("无法移除不存在的id!");return;
        }
        states.Remove(id);
    }
    //根据转化条件转化状态
    public void PerformTransition(Transition tran)
    {
        if (tran==Transition.DefualtNull)
        {
            Debug.Log("转化条件为空,状态无法进行转化!");return;
        }
        StateID _id = currentFSM.GetOutputState(tran);
        if (_id==StateID.NullState)
        {
            Debug.Log("状态为空,无法进行转化!");return;
        }
        if (!states.ContainsKey(_id))
        {
            Debug.Log("状态字典中不存在状态,无法转化!");return;
        }
        FSMState _state = states[_id];
        currentFSM.DoBeforLeaving();//当前状态离开调用方法
        currentFSM = _state;
        currentStateID = _id;
        currentFSM.DoBeforEnter();//新的状态进入调用方法
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值