Unity有限状态机

参考:http://www.cnblogs.com/unity3/archive/2013/04/05/3000692.html

但是原作者代码有点问题,自己进行了改写

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

public enum Translate
{
    NullTrans,
    SeePlayer,
    PlayerStop
}
public enum StateID
{
    NullState,
    Idle,
    FollowPlayer,
}
public abstract class FMS_State
{
    private StateID id;
    public StateID ID
    {
        set { id = value; }
        get { return id; }
    }
    public virtual void DoBeforeEnter() { }
    public virtual void DoBeforeMoveing() { }
    public abstract void Reason(GameObject player, GameObject NPC); 
    public abstract void Act(GameObject player, GameObject NPC);
}
public class Idle_State : FMS_State
{
    FMS_Machine_Manage _fms_machine_Manage;
    public Idle_State(FMS_Machine_Manage mrg)
    {
        _fms_machine_Manage = mrg;
        ID = StateID.Idle;
    }
    public override void Reason(GameObject player, GameObject NPC)
    {
        if (Input.GetKeyDown(KeyCode.Z))
        {
            _fms_machine_Manage.changeState(Translate.SeePlayer);
        }

    }
    public override void Act(GameObject player, GameObject NPC)
    {
        Debug.Log("Act_Idle");
    }
}
public class Follow_State : FMS_State
{
    FMS_Machine_Manage _fms_machine_Manage;
    public Follow_State(FMS_Machine_Manage mrg)
    {
        _fms_machine_Manage = mrg;
        ID = StateID.FollowPlayer;
    }
    public override void Reason(GameObject player, GameObject NPC)
    {
        if (Input.GetKeyDown(KeyCode.X))
        {
            _fms_machine_Manage.changeState(Translate.PlayerStop);
        }
    }
    public override void Act(GameObject player, GameObject NPC)
    {
        Debug.Log("Act_Follow");
    }
}
public class FMS_Machine_Manage : MonoBehaviour {
    private List<FMS_State> states;
    private Dictionary<Translate, StateID> map = new Dictionary<Translate, StateID>();
    private FMS_State currentState;
    private StateID currentStateID;

    public GameObject player;
    public GameObject NPC;
    public FMS_State CurrentState
    {
        set { currentState = value; }
        get { return currentState; }
    }

    public StateID CurrentStateID
    {
        set { currentStateID = value; }
        get { return currentStateID; }
    }
    public void UpdateFunction()
    {

        CurrentState.Reason(player, NPC);
        CurrentState.Act(player, NPC);
    }
    void Awake()
    {
        states = new List<FMS_State>();
    }
    public void addDictionary(Translate tr, StateID id1)
    {
        if (tr == Translate.NullTrans)
        {
            Debug.LogError("Null Trans is not allower to adding into");
            return;
        }

        if (id1 == StateID.NullState)
        {
            Debug.LogError("Null State id not ~~~");
            return;

        }
        if (map.ContainsKey(tr))
        {
            Debug.LogError(id1.ToString() + "is already added to");
            return;
        }
        map.Add(tr, id1);
    }
    public void deleateDictionary(Translate tr)
    {
        if (tr == Translate.NullTrans)
        {
            Debug.LogError("TransNull is not allowed to delate");
            return;
        }
        if (map.ContainsKey(tr))
        {
            map.Remove(tr);
            return;
        }
        Debug.LogError(tr.ToString() + "are not exist");
    }
    public StateID GetOutState(Translate tr)
    {
        if (map.ContainsKey(tr))
        {
            return map[tr];
        }
        return StateID.NullState;
    }
    public void MakeFMSMachine()
    {
        Idle_State idle = new Idle_State(this);
        Follow_State follow = new Follow_State(this);
        AddFmsState(idle);
        AddFmsState(follow);
        addDictionary(Translate.PlayerStop, StateID.Idle);
        addDictionary(Translate.SeePlayer, StateID.FollowPlayer);
    }
    public void AddFmsState(FMS_State s)
    {
        if (s == null)
        {
            Debug.LogError(" Null reference is not allowed");
        }

        if (states.Count == 0)
        {
            states.Add(s);                   
            currentState = s;
            currentStateID = s.ID;
            return;
        }
        foreach (FMS_State state in states)
        {
            if (state == s)
            {
                Debug.LogError(s.ID.ToString() + "has already been added");
                return;
            }
        }
        states.Add(s);
    }
    public void delateFmsState(StateID id)
    {
        if (id == StateID.NullState)
        {
            Debug.LogError("NullStateID is not allowed for a real state");
            return;
        }

        foreach (FMS_State state in states)
        {
            if (state.ID == id)
            {
                states.Remove(state);
                return;
            }
        }
    }
    public void changeState(Translate tr)
    {
        if (tr == Translate.NullTrans)
        {
            Debug.LogError("NullTransition is not allowed for a real transition");
            return;
        }
        StateID id = GetOutState(tr);
        currentStateID = id;
        foreach (FMS_State state in states)
        {
            if (currentStateID == state.ID)
            {
                CurrentState.DoBeforeMoveing(); 
                currentState = state;
                CurrentState.DoBeforeEnter();
                break;
            }

        }
    }
}

猜你喜欢

转载自blog.csdn.net/aila852/article/details/78200509
今日推荐