FSM實現敵人簡單AI


管理類:

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

/// <summary>
/// 管理類
/// </summary>
public class FSMSystem  {
    public Dictionary<StateID, FSMState> states = new Dictionary<StateID, FSMState>();
    
    private StateID currentStateID;
    private FSMState currentState;


    public void Update(GameObject obj)
    {
        
        currentState.Act(obj);
        currentState.Reason(obj);
    }

    /// <summary>
    /// 添加狀態
    /// </summary>
    /// <param name="s">狀態</param>
    public void AddState(FSMState s)
    {
        if(s==null)
        {
            Debug.LogError("FSMState爲空");
            return;
        }
        if (currentState ==null)
        {
            currentState = s;
            currentStateID = s.ID;
        }
        if (states .ContainsKey (s.ID))
        {
            Debug.LogError("該狀態已存在");
            return;
        }
        states.Add(s.ID, s);
    }
    /// <summary>
    /// 狀態刪除
    /// </summary>
    /// <param name="id"></param>
    public void DelegateState(StateID id)
    {
        if(id ==StateID .NullStateID)
        {
            Debug.LogError("無法刪除空狀態");
            return;
        }
        if (states .ContainsKey (id )==false)
        {
            Debug.LogError("無法刪除不存在的狀態");
            return;
        }
        states.Remove(id);
    }
    
    /// <summary>
    /// 狀態轉換
    /// </summary>
    /// <param name="trans"></param>
    public void PerfromTransition(Transition trans)
    {
       if(trans==Transition.NullTransition)
        {
            Debug.LogError("空的轉換條件");
            return;
        }
        StateID id = currentState.GetOutputState(trans);
        if (id == StateID.NullStateID)
        {
            Debug.LogError("無法根據條件轉換");
            return;
        }
        if (states.ContainsKey(id )==false)
        {
            Debug.LogError("狀態機裏不存在該轉態,無法轉換");
            return;
        }
        FSMState state = states[id];
        currentState.DoAdterLeaving();
        currentState = state;
        currentStateID = id;
        currentState.DoBeforEntering();
    }
}

基類:

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

public enum Transition
{
    NullTransition=0,
    /// <summary>
    /// 看見主角
    /// </summary>
    SeePlayer,
    /// <summary>
    /// 主角消失
    /// </summary>
    LostPlayer
}
public enum StateID
{
    NullStateID=0,
    /// <summary>
    /// 巡邏
    /// </summary>
    Patorl,
    /// <summary>
    /// 追逐主角
    /// </summary>
    Chase
}


/// <summary>
/// 狀態基類
/// </summary>
public abstract   class FSMState {
    protected StateID stateID;
    public StateID ID {get{return stateID ;}}
    protected Dictionary<Transition, StateID> map = new Dictionary<Transition, StateID>();

    protected FSMSystem fsm;
    protected FSMState(FSMSystem fsm )
    {
        this.fsm = fsm;
    }
    
    /// <summary>
    /// 添加狀態
    /// </summary>
    /// <param name="trans"></param>
    /// <param name="id"></param>
    public void Addtransition(Transition  trans,StateID id)
    {
        if (trans == Transition.NullTransition)
        {
            Debug.LogError("不允許NullTransition");
            return;
        }
        if (id  == StateID .NullStateID)
        {
            Debug.LogError("不允許Nullstate");
            return;
        }
        if (map .ContainsKey (trans ))
        {
            Debug.LogError("已存在");
            return;
        }
        map.Add(trans, id);
    }
    /// <summary>
    /// 刪除狀態
    /// </summary>
    /// <param name="trans"></param>
    public void DeleteTransition(Transition trans)
    {
        if (trans == Transition.NullTransition)
        {
            Debug.LogError("不允許NullTransition");
            return;
        }
        
        if (map.ContainsKey(trans)==false )
        {
            Debug.LogError("不存在");
            return;
        }

        map.Remove(trans);
    }

    /// <summary>
    /// 判斷當前狀態
    /// </summary>
    /// <param name="trans"></param>
    /// <returns></returns>
    public StateID GetOutputState(Transition trans)
    {
        if (map.ContainsKey (trans))
        {
            return map[trans];
        }
        return StateID.NullStateID;
    }


    /// <summary>
    /// 進入狀態之前所做的狀態
    /// </summary>
    public  virtual void DoBeforEntering() { }
    /// <summary>
    /// 離開狀態的時候
    /// </summary>
    public virtual void DoAdterLeaving() { }

    /// <summary>
    /// 在當前狀態下要做的事情
    /// </summary>
    public abstract void Act(GameObject obj);

    /// <summary>
    /// 判斷轉換條件
    /// </summary>
    public abstract void  Reason(GameObject obj);
}

兩個AI狀態:1

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 巡邏狀態
/// </summary>
public class PatrolState : FSMState
{
    private List <Transform > path=new List<Transform> ();
    private int index = 0;

    private Transform playerTransform;

    public float jvLi = 3;

    public PatrolState (FSMSystem fsm):base (fsm)
    {
        stateID = StateID.Patorl;
        Transform pathTransform = GameObject.Find("Path").transform;
        Transform[] children = pathTransform.GetComponentsInChildren<Transform > ();
        foreach (Transform  item in children )
        {
            if (item !=pathTransform)
            {
                path.Add(item);                      
            }                                        
        }
        playerTransform = GameObject.FindGameObjectWithTag(StringText .Player ).transform;                                             
    }                  
    /// <summary>
    /// 處於當前狀態時要做的事
    /// </summary>
    /// <param name="obj"></param>
    public override void Act(GameObject obj)
    {
        obj.transform.LookAt(path[index].position );
        obj.transform.Translate(Vector3.forward * Time.deltaTime * 2);
        if (Vector3 .Distance (obj.transform .position ,path[index ].position) < 0.5f)
        {
            index++;
            index %= path.Count;
        }
    }
    /// <summary>
    /// 判斷轉換條件
    /// </summary>
    /// <param name="obj"></param>
    public override void Reason(GameObject obj)
    {
        //throw new System.NotImplementedException();
        if (Vector3 .Distance (playerTransform .position ,obj .transform .position) < jvLi )
        {
            fsm.PerfromTransition(Transition.SeePlayer);
        }
    }
}

2

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

/// <summary>
/// 追逐Player
/// </summary>
public class ChaseState : FSMState
{
    public float speed = 2;
    private Transform playerTransform;
    private float jvLi=6;

    public  ChaseState(FSMSystem fsm) : base(fsm)
    {
        stateID = StateID.Chase;
        playerTransform = GameObject.FindGameObjectWithTag(StringText.Player).transform;
    }

    public override void Act(GameObject obj)
    {
        obj.transform.LookAt(playerTransform.position);
        obj.transform.Translate(Vector3.forward * speed * Time.deltaTime);
    }

    public override void Reason(GameObject obj)
    {
        if (Vector3.Distance(playerTransform.position, obj.transform.position) > jvLi)
        {
            fsm.PerfromTransition(Transition.LostPlayer);
        }
    }
}

調用:

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

/// <summary>
/// 敵人
/// </summary>
public class Enemy : MonoBehaviour {

    FSMSystem fsm;
	void Start () {
        fsm = new FSMSystem();
        

        FSMState patrolState = new PatrolState(fsm);
        patrolState.Addtransition(Transition.SeePlayer, StateID.Chase);

        FSMState chaseState = new ChaseState(fsm);
        chaseState.Addtransition(Transition.LostPlayer, StateID.Patorl);

        fsm.AddState(patrolState);
        fsm.AddState(chaseState);

        
	}
	

	void Update () {
        fsm.Update(this.gameObject);
	}
}

發佈了58 篇原創文章 · 獲贊 2 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章