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);
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值