1. 程式人生 > >Unity3D有限狀態機的使用

Unity3D有限狀態機的使用

FSM(有限狀態機):多型

在各個小狀態類中因為是在保持動作的過程中執行的退出動作,所以將退出動畫的函式放在了保持動畫的函式中

在各個小狀態的類中判斷狀態是否在執行是根據動畫本身的播放屬性來判斷的,與其它的無關,是動畫自己的事情

簡而言之:在英雄類中的Update中做的事情就是切換狀態,而在LateUpdate(),做的事情就是時刻監測狀態播放是否結束,如果結束那麼就回到預設狀態;如果沒有就繼續播放動畫

第一部分構造狀態機器:

第一個類:狀態父類1.

using UnityEngine;

using System.Collections;

public class stateBase  

{

    public int ID{ get; set;}

    public stateMachine nachine;//自己的狀態被哪個機器控制。

    public  stateBase(int i)

    {

        this.ID = i;

    }

    public virtual void OnEnter(params object [] args)//引數的意思:可以傳引數也可以不傳引數;

    {

    }

    public virtual void OnStay(params object [] args)

    {

    }

    public virtual void OnExit(params object [] args)

    {

    }

    //給每一個狀態設定一個id;

    //有一個要控制自己狀態的狀態機。

    //建構函式

    //虛方法(當前狀態的進入,當前狀態的保持,當前狀態的退出);

}

第二個類:確定這個狀態機屬於那個物件,繼承自stateBase;

using UnityEngine;

using System.Collections;

public class 

<T> : stateBase {

    public T owner;

    public stateTemplate (int _id, T _owner) : base (_id)

    {

        owner = _owner;

    }

    //狀態的擁有者(當前狀態歸屬於哪一個物件,有可能是英雄,有可能是敵人);

    // Use this for initialization

    void Start () {

    }

    // Update is called once per frame

    void Update () {

    }

}

狀態的類

1,預設狀態類

using UnityEngine;

using System.Collections;

public class IdleSatae : stateTemplate<Player> {

    public IdleSatae (int id,Player p):base(id,p)

    {

    }

    public override void OnEnter (params object[] args)

    {

        base.OnEnter (args);

        owner.ani.Play ("Idle");

    }

    public override void OnStay (params object[] args)

    {

        base.OnStay (args);

        if (owner.ani.IsPlaying ("Idle") == false) {

        this.OnExit ();

        }

    }

    public override void OnExit (params object[] args)

    {

        base.OnExit (args);

    }

    // Use this for initialization

    void Start () {

    }

    // Update is called once per frame

    void Update () {

    }

}

2,攻擊狀態類

using UnityEngine;

using System.Collections;

public class AttackSatae : stateTemplate<Player> {

    public AttackSatae (int id,Player p):base(id,p)

    {

    }

    public override void OnEnter (params object[] args)

    {

        base.OnEnter (args);

        owner.ani.Play ("Attack");

    }

    public override void OnStay (params object[] args)//因為是在保持動作的過程中執行的退出動作,所以將退出動畫的函式放在了保持動畫的函式中

    {

        base.OnStay (args);

        if (owner.ani.IsPlaying ("Attack") == false)

        {

            this.OnExit ();

        }

    }

    public override void OnExit (params object[] args)

    {

        base.OnExit (args);

        //退出的時候想辦法由攻擊狀態回到 Idle

        owner.playstate = PlayerState.Idle;

    }

    // Use this for initialization

    void Start () {

    }

    // Update is called once per frame

    void Update () {

    }

}

3,防禦狀態類

using UnityEngine;

using System.Collections;

public class JumpSatae : stateTemplate<Player> {

    public JumpSatae (int id,Player p):base(id,p)

    {

    }

    public override void OnEnter (params object[] args)

    {

        base.OnEnter (args);

        owner.ani.Play ("Jump");

    }

    public override void OnStay (params object[] args)

    {

        base.OnStay (args);

        if (owner.ani.IsPlaying ("Jump") == false)

        {

            this.OnExit ();

        }

    }

    public override void OnExit (params object[] args)

    {

        base.OnExit (args);

        owner.playstate = PlayerState.Idle;

        //退出的時候想辦法由攻擊狀態回到 Idle

    }

}

主角:狀態機類:

using UnityEngine;

using System.Collections;

using System.Collections.Generic;

public class stateMachine  

{

    public Dictionary<int,stateBase> m_stateBase;

    public stateBase m_currentStater;//記錄當前狀態

    public stateBase m_PreviouStarter;//記錄當前狀態的上一個狀態

    //狀態機器

    //一個集合儲存所有狀態,有建構函式,儲存狀態方法,狀態保持,最後是改變狀態

    //機器生產出來以後,就應該有一個預設狀態被執行,所以建構函式應該傳遞預設的狀態,並且播放它

    public stateMachine(stateBase beganStarter)

    {

        m_PreviouStarter = null;

        m_currentStater = beganStarter;

        m_stateBase = new Dictionary<int, stateBase> ();

        RegisterState (beganStarter);

        m_currentStater.OnEnter ();

    }

    public void RegisterState(stateBase sb)

    {

        if (m_stateBase.ContainsKey (sb.ID)) {

            return;

        } 

        m_stateBase.Add (sb.ID,sb);

        sb.nachine = this;//表示sb這個狀態被當前狀態機所控制

    }

    public void FSMUpdate()//保持狀態

    {

        if (m_currentStater != null) //表示如果有這個狀態就始終執行這個方法 保持住狀態

        {

            m_currentStater.OnStay ();

        }

    }

    public void TranslateState(int id,params object [] args)//切換狀態

    {

        if (!m_stateBase.ContainsKey (id)) {

            return;

        }

        m_PreviouStarter = m_currentStater;

        m_currentStater = m_stateBase [id];

        m_currentStater.OnEnter ();

    }

}

第二部分使用狀態機;

英雄類:

using UnityEngine;

using System.Collections;

public enum PlayerState

{

    Idle,

    Attack,

    Jump,

}

public class Player : MonoBehaviour {

    public stateMachine m_stateMachine;

    public  Animation ani;

    public PlayerState playstate = PlayerState.Idle;

    //記錄狀態

    //控制機器

    void Start () {

        //初始化機器

        m_stateMachine = new stateMachine (new IdleSatae(0,this));

        //把所有狀態新增到字典中,用來改變狀態;

        m_stateMachine.RegisterState (new AttackSatae(1,this));

        m_stateMachine.RegisterState (new JumpSatae(2,this));

    }

    void Update () {

        if (Input.GetKey (KeyCode.A)) {

            playstate = PlayerState.Attack;

        }

        if (Input.GetKey (KeyCode.D)) {

            playstate = PlayerState.Jump;

        }

        PlayAi ();

    }

    void PlayAi()

    {

        switch (playstate) {

        case PlayerState.Idle:

            m_stateMachine.TranslateState (0);

            break;

        case PlayerState.Attack:

            m_stateMachine.TranslateState (1);

            break;

        case PlayerState.Jump:

            m_stateMachine.TranslateState (2);

            break;

        default:

            break;

        }

    }

    void LateUpdate()

    {

        m_stateMachine.FSMUpdate ();

    }

}

FSM(有限狀態機):多型

在各個小狀態類中因為是在保持動作的過程中執行的退出動作,所以將退出動畫的函式放在了保持動畫的函式中

在各個小狀態的類中判斷狀態是否在執行是根據動畫本身的播放屬性來判斷的,與其它的無關,是動畫自己的事情

簡而言之:在英雄類中的Update中做的事情就是切換狀態,而在LateUpdate(),做的事情就是時刻監測狀態播放是否結束,如果結束那麼就回到預設狀態;如果沒有就繼續播放動畫

第一部分構造狀態機器:

第一個類:狀態父類1.

using UnityEngine;

using System.Collections;

public class stateBase  

{

    public int ID{ get; set;}

    public stateMachine nachine;//自己的狀態被哪個機器控制。

    public  stateBase(int i)

    {

        this.ID = i;

    }

    public virtual void OnEnter(params object [] args)//引數的意思:可以傳引數也可以不傳引數;

    {

    }

    public virtual void OnStay(params object [] args)

    {

    }

    public virtual void OnExit(params object [] args)

    {

    }

    //給每一個狀態設定一個id;

    //有一個要控制自己狀態的狀態機。

    //建構函式

    //虛方法(當前狀態的進入,當前狀態的保持,當前狀態的退出);

}

第二個類:確定這個狀態機屬於那個物件,繼承自stateBase;

using UnityEngine;

using System.Collections;

public class 

<T> : stateBase {

    public T owner;

    public stateTemplate (int _id, T _owner) : base (_id)

    {

        owner = _owner;

    }

    //狀態的擁有者(當前狀態歸屬於哪一個物件,有可能是英雄,有可能是敵人);

    // Use this for initialization

    void Start () {

    }

    // Update is called once per frame

    void Update () {

    }

}

狀態的類

1,預設狀態類

using UnityEngine;

using System.Collections;

public class IdleSatae : stateTemplate<Player> {

    public IdleSatae (int id,Player p):base(id,p)

    {

    }

    public override void OnEnter (params object[] args)

    {

        base.OnEnter (args);

        owner.ani.Play ("Idle");

    }

    public override void OnStay (params object[] args)

    {

        base.OnStay (args);

        if (owner.ani.IsPlaying ("Idle") == false) {

        this.OnExit ();

        }

    }

    public override void OnExit (params object[] args)

    {

        base.OnExit (args);

    }

    // Use this for initialization

    void Start () {

    }

    // Update is called once per frame

    void Update () {

    }

}

2,攻擊狀態類

using UnityEngine;

using System.Collections;

public class AttackSatae : stateTemplate<Player> {

    public AttackSatae (int id,Player p):base(id,p)

    {

    }

    public override void OnEnter (params object[] args)

    {

        base.OnEnter (args);

        owner.ani.Play ("Attack");

    }

    public override void OnStay (params object[] args)//因為是在保持動作的過程中執行的退出動作,所以將退出動畫的函式放在了保持動畫的函式中

    {

        base.OnStay (args);

        if (owner.ani.IsPlaying ("Attack") == false)

        {

            this.OnExit ();

        }

    }

    public override void OnExit (params object[] args)

    {

        base.OnExit (args);

        //退出的時候想辦法由攻擊狀態回到 Idle

        owner.playstate = PlayerState.Idle;

    }

    // Use this for initialization

    void Start () {

    }

    // Update is called once per frame

    void Update () {

    }

}

3,防禦狀態類

using UnityEngine;

using System.Collections;

public class JumpSatae : stateTemplate<Player> {

    public JumpSatae (int id,Player p):base(id,p)

    {

    }

    public override void OnEnter (params object[] args)

    {

        base.OnEnter (args);

        owner.ani.Play ("Jump");

    }

    public override void OnStay (params object[] args)

    {

        base.OnStay (args);

        if (owner.ani.IsPlaying ("Jump") == false)

        {

            this.OnExit ();

        }

    }

    public override void OnExit (params object[] args)

    {

        base.OnExit (args);

        owner.playstate = PlayerState.Idle;

        //退出的時候想辦法由攻擊狀態回到 Idle

    }

}

主角:狀態機類:

using UnityEngine;

using System.Collections;

using System.Collections.Generic;

public class stateMachine  

{

    public Dictionary<int,stateBase> m_stateBase;

    public stateBase m_currentStater;//記錄當前狀態

    public stateBase m_PreviouStarter;//記錄當前狀態的上一個狀態

    //狀態機器

    //一個集合儲存所有狀態,有建構函式,儲存狀態方法,狀態保持,最後是改變狀態

    //機器生產出來以後,就應該有一個預設狀態被執行,所以建構函式應該傳遞預設的狀態,並且播放它

    public stateMachine(stateBase beganStarter)

    {

        m_PreviouStarter = null;

        m_currentStater = beganStarter;

        m_stateBase = new Dictionary<int, stateBase> ();

        RegisterState (beganStarter);

        m_currentStater.OnEnter ();

    }

    public void RegisterState(stateBase sb)

    {

        if (m_stateBase.ContainsKey (sb.ID)) {

            return;

        } 

        m_stateBase.Add (sb.ID,sb);

        sb.nachine = this;//表示sb這個狀態被當前狀態機所控制

    }

    public void FSMUpdate()//保持狀態

    {

        if (m_currentStater != null) //表示如果有這個狀態就始終執行這個方法 保持住狀態

        {

            m_currentStater.OnStay ();

        }

    }

    public void TranslateState(int id,params object [] args)//切換狀態

    {

        if (!m_stateBase.ContainsKey (id)) {

            return;

        }

        m_PreviouStarter = m_currentStater;

        m_currentStater = m_stateBase [id];

        m_currentStater.OnEnter ();

    }

}

第二部分使用狀態機;

英雄類:

using UnityEngine;

using System.Collections;

public enum PlayerState

{

    Idle,

    Attack,

    Jump,

}

public class Player : MonoBehaviour {

    public stateMachine m_stateMachine;

    public  Animation ani;

    public PlayerState playstate = PlayerState.Idle;

    //記錄狀態

    //控制機器

    void Start () {

        //初始化機器

        m_stateMachine = new stateMachine (new IdleSatae(0,this));

        //把所有狀態新增到字典中,用來改變狀態;

        m_stateMachine.RegisterState (new AttackSatae(1,this));

        m_stateMachine.RegisterState (new JumpSatae(2,this));

    }

    void Update () {

        if (Input.GetKey (KeyCode.A)) {

            playstate = PlayerState.Attack;

        }

        if (Input.GetKey (KeyCode.D)) {

            playstate = PlayerState.Jump;

        }

        PlayAi ();

    }

    void PlayAi()

    {

        switch (playstate) {

        case PlayerState.Idle:

            m_stateMachine.TranslateState (0);

            break;

        case PlayerState.Attack:

            m_stateMachine.TranslateState (1);

            break;

        case PlayerState.Jump:

            m_stateMachine.TranslateState (2);

            break;

        default:

            break;

        }

    }

    void LateUpdate()

    {

        m_stateMachine.FSMUpdate ();

    }

}

FSM(有限狀態機):多型

在各個小狀態類中因為是在保持動作的過程中執行的退出動作,所以將退出動畫的函式放在了保持動畫的函式中

在各個小狀態的類中判斷狀態是否在執行是根據動畫本身的播放屬性來判斷的,與其它的無關,是動畫自己的事情

簡而言之:在英雄類中的Update中做的事情就是切換狀態,而在LateUpdate(),做的事情就是時刻監測狀態播放是否結束,如果結束那麼就回到預設狀態;如果沒有就繼續播放動畫

第一部分構造狀態機器:

第一個類:狀態父類1.

using UnityEngine;

using System.Collections;

public class stateBase  

{

    public int ID{ get; set;}

    public stateMachine nachine;//自己的狀態被哪個機器控制。

    public  stateBase(int i)

    {

        this.ID = i;

    }

    public virtual void OnEnter(params object [] args)//引數的意思:可以傳引數也可以不傳引數;

    {

    }

    public virtual void OnStay(params object [] args)

    {

    }

    public virtual void OnExit(params object [] args)

    {

    }

    //給每一個狀態設定一個id;

    //有一個要控制自己狀態的狀態機。

    //建構函式

    //虛方法(當前狀態的進入,當前狀態的保持,當前狀態的退出);

}

第二個類:確定這個狀態機屬於那個物件,繼承自stateBase;

using UnityEngine;

using System.Collections;

public class 

<T> : stateBase {

    public T owner;

    public stateTemplate (int _id, T _owner) : base (_id)

    {

        owner = _owner;

    }

    //狀態的擁有者(當前狀態歸屬於哪一個物件,有可能是英雄,有可能是敵人);

    // Use this for initialization

    void Start () {

    }

    // Update is called once per frame

    void Update () {

    }

}

狀態的類

1,預設狀態類

using UnityEngine;

using System.Collections;

public class IdleSatae : stateTemplate<Player> {

    public IdleSatae (int id,Player p):base(id,p)

    {

    }

    public override void OnEnter (params object[] args)

    {

        base.OnEnter (args);

        owner.ani.Play ("Idle");

    }

    public override void OnStay (params object[] args)

    {

        base.OnStay (args);

        if (owner.ani.IsPlaying ("Idle") == false) {

        this.OnExit ();

        }

    }

    public override void OnExit (params object[] args)

    {

        base.OnExit (args);

    }

    // Use this for initialization

    void Start () {

    }

    // Update is called once per frame

    void Update () {

    }

}

2,攻擊狀態類

using UnityEngine;

using System.Collections;

public class AttackSatae : stateTemplate<Player> {

    public AttackSatae (int id,Player p):base(id,p)

    {

    }

    public override void OnEnter (params object[] args)

    {

        base.OnEnter (args);

        owner.ani.Play ("Attack");

    }

    public override void OnStay (params object[] args)//因為是在保持動作的過程中執行的退出動作,所以將退出動畫的函式放在了保持動畫的函式中

    {

        base.OnStay (args);

        if (owner.ani.IsPlaying ("Attack") == false)

        {

            this.OnExit ();

        }

    }

    public override void OnExit (params object[] args)

    {

        base.OnExit (args);

        //退出的時候想辦法由攻擊狀態回到 Idle

        owner.playstate = PlayerState.Idle;

    }

    // Use this for initialization

    void Start () {

    }

    // Update is called once per frame

    void Update () {

    }

}

3,防禦狀態類

using UnityEngine;

using System.Collections;

public class JumpSatae : stateTemplate<Player> {

    public JumpSatae (int id,Player p):base(id,p)

    {

    }

    public override void OnEnter (params object[] args)

    {

        base.OnEnter (args);

        owner.ani.Play ("Jump");

    }

    public override void OnStay (params object[] args)

    {

        base.OnStay (args);

        if (owner.ani.IsPlaying ("Jump") == false)

        {

            this.OnExit ();

        }

    }

    public override void OnExit (params object[] args)

    {

        base.OnExit (args);

        owner.playstate = PlayerState.Idle;

        //退出的時候想辦法由攻擊狀態回到 Idle

    }

}

主角:狀態機類:

using UnityEngine;

using System.Collections;

using System.Collections.Generic;

public class stateMachine  

{

    public Dictionary<int,stateBase> m_stateBase;

    public stateBase m_currentStater;//記錄當前狀態

    public stateBase m_PreviouStarter;//記錄當前狀態的上一個狀態

    //狀態機器

    //一個集合儲存所有狀態,有建構函式,儲存狀態方法,狀態保持,最後是改變狀態

    //機器生產出來以後,就應該有一個預設狀態被執行,所以建構函式應該傳遞預設的狀態,並且播放它

    public stateMachine(stateBase beganStarter)

    {

        m_PreviouStarter = null;

        m_currentStater = beganStarter;

        m_stateBase = new Dictionary<int, stateBase> ();

        RegisterState (beganStarter);

        m_currentStater.OnEnter ();

    }

    public void RegisterState(stateBase sb)

    {

        if (m_stateBase.ContainsKey (sb.ID)) {

            return;

        } 

        m_stateBase.Add (sb.ID,sb);

        sb.nachine = this;//表示sb這個狀態被當前狀態機所控制

    }

    public void FSMUpdate()//保持狀態

    {

        if (m_currentStater != null) //表示如果有這個狀態就始終執行這個方法 保持住狀態

        {

            m_currentStater.OnStay ();

        }

    }

    public void TranslateState(int id,params object [] args)//切換狀態

    {

        if (!m_stateBase.ContainsKey (id)) {

            return;

        }

        m_PreviouStarter = m_currentStater;

        m_currentStater = m_stateBase [id];

        m_currentStater.OnEnter ();

    }

}

第二部分使用狀態機;

英雄類:

using UnityEngine;

using System.Collections;

public enum PlayerState

{

    Idle,

    Attack,

    Jump,

}

public class Player : MonoBehaviour {

    public stateMachine m_stateMachine;

    public  Animation ani;

    public PlayerState playstate = PlayerState.Idle;

    //記錄狀態

    //控制機器

    void Start () {

        //初始化機器

        m_stateMachine = new stateMachine (new IdleSatae(0,this));

        //把所有狀態新增到字典中,用來改變狀態;

        m_stateMachine.RegisterState (new AttackSatae(1,this));

        m_stateMachine.RegisterState (new JumpSatae(2,this));

    }

    void Update () {

        if (Input.GetKey (KeyCode.A)) {

            playstate = PlayerState.Attack;

        }

        if (Input.GetKey (KeyCode.D)) {

            playstate = PlayerState.Jump;

        }

        PlayAi ();

    }

    void PlayAi()

    {

        switch (playstate) {

        case PlayerState.Idle:

            m_stateMachine.TranslateState (0);

            break;

        case PlayerState.Attack:

            m_stateMachine.TranslateState (1);

            break;

        case PlayerState.Jump:

            m_stateMachine.TranslateState (2);

            break;

        default:

            break;

        }

    }

    void LateUpdate()

    {

        m_stateMachine.FSMUpdate ();

    }

}

FSM(有限狀態機):多型

在各個小狀態類中因為是在保持動作的過程中執行的退出動作,所以將退出動畫的函式放在了保持動畫的函式中

在各個小狀態的類中判斷狀態是否在執行是根據動畫本身的播放屬性來判斷的,與其它的無關,是動畫自己的事情

簡而言之:在英雄類中的Update中做的事情就是切換狀態,而在LateUpdate(),做的事情就是時刻監測狀態播放是否結束,如果結束那麼就回到預設狀態;如果沒有就繼續播放動畫

第一部分構造狀態機器:

第一個類:狀態父類1.

using UnityEngine;

using System.Collections;

public class stateBase  

{

    public int ID{ get; set;}

    public stateMachine nachine;//自己的狀態被哪個機器控制。

    public  stateBase(int i)

    {

        this.ID = i;

    }

    public virtual void OnEnter(params object [] args)//引數的意思:可以傳引數也可以不傳引數;

    {

    }

    public virtual void OnStay(params object [] args)

    {

    }

    public virtual void OnExit(params object [] args)

    {

    }

    //給每一個狀態設定一個id;

    //有一個要控制自己狀態的狀態機。

    //建構函式

    //虛方法(當前狀態的進入,當前狀態的保持,當前狀態的退出);

}

第二個類:確定這個狀態機屬於那個物件,繼承自stateBase;

using UnityEngine;

using System.Collections;

public class 

<T> : stateBase {

    public T owner;

    public stateTemplate (int _id, T _owner) : base (_id)

    {

        owner = _owner;

    }

    //狀態的擁有者(當前狀態歸屬於哪一個物件,有可能是英雄,有可能是敵人);

    // Use this for initialization

    void Start () {

    }

    // Update is called once per frame

    void Update () {

    }

}

狀態的類

1,預設狀態類

using UnityEngine;

using System.Collections;

public class IdleSatae : stateTemplate<Player> {

    public IdleSatae (int id,Player p):base(id,p)

    {

    }

    public override void OnEnter (params object[] args)

    {

        base.OnEnter (args);

        owner.ani.Play ("Idle");

    }

    public override void OnStay (params object[] args)

    {

        base.OnStay (args);

        if (owner.ani.IsPlaying ("Idle") == false) {

        this.OnExit ();

        }

    }

    public override void OnExit (params object[] args)

    {

        base.OnExit (args);

    }

    // Use this for initialization

    void Start () {

    }

    // Update is called once per frame

    void Update () {

    }

}

2,攻擊狀態類

using UnityEngine;

using System.Collections;

public class AttackSatae : stateTemplate<Player> {

    public AttackSatae (int id,Player p):base(id,p)

    {

    }

    public override void OnEnter (params object[] args)

    {

        base.OnEnter (args);

        owner.ani.Play ("Attack");

    }

    public override void OnStay (params object[] args)//因為是在保持動作的過程中執行的退出動作,所以將退出動畫的函式放在了保持動畫的函式中

    {

        base.OnStay (args);

        if (owner.ani.IsPlaying ("Attack") == false)

        {

            this.OnExit ();

        }

    }

    public override void OnExit (params object[] args)

    {

        base.OnExit (args);

        //退出的時候想辦法由攻擊狀態回到 Idle

        owner.playstate = PlayerState.Idle;

    }

    // Use this for initialization

    void Start () {

    }

    // Update is called once per frame

    void Update () {

    }

}

3,防禦狀態類

using UnityEngine;

using System.Collections;

public class JumpSatae : stateTemplate<Player> {

    public JumpSatae (int id,Player p):base(id,p)

    {

    }

    public override void OnEnter (params object[] args)

    {

        base.OnEnter (args);

        owner.ani.Play ("Jump");

    }

    public override void OnStay (params object[] args)

    {

        base.OnStay (args);

        if (owner.ani.IsPlaying ("Jump") == false)

        {

            this.OnExit ();

        }

    }

    public override void OnExit (params object[] args)

    {

        base.OnExit (args);

        owner.playstate = PlayerState.Idle;

        //退出的時候想辦法由攻擊狀態回到 Idle

    }

}

主角:狀態機類:

using UnityEngine;

using System.Collections;

using System.Collections.Generic;

public class stateMachine  

{

    public Dictionary<int,stateBase> m_stateBase;

    public stateBase m_currentStater;//記錄當前狀態

    public stateBase m_PreviouStarter;//記錄當前狀態的上一個狀態

    //狀態機器

    //一個集合儲存所有狀態,有建構函式,儲存狀態方法,狀態保持,最後是改變狀態

    //機器生產出來以後,就應該有一個預設狀態被執行,所以建構函式應該傳遞預設的狀態,並且播放它

    public stateMachine(stateBase beganStarter)

    {

        m_PreviouStarter = null;

        m_currentStater = beganStarter;

        m_stateBase = new Dictionary<int, stateBase> ();

        RegisterState (beganStarter);

        m_currentStater.OnEnter ();

    }

    public void RegisterState(stateBase sb)

    {

        if (m_stateBase.ContainsKey (sb.ID)) {

            return;

        } 

        m_stateBase.Add (sb.ID,sb);

        sb.nachine = this;//表示sb這個狀態被當前狀態機所控制

    }

    public void FSMUpdate()//保持狀態

    {

        if (m_currentStater != null) //表示如果有這個狀態就始終執行這個方法 保持住狀態

        {

            m_currentStater.OnStay ();

        }

    }

    public void TranslateState(int id,params object [] args)//切換狀態

    {

        if (!m_stateBase.ContainsKey (id)) {

            return;

        }

        m_PreviouStarter = m_currentStater;

        m_currentStater = m_stateBase [id];

        m_currentStater.OnEnter ();

    }

}

第二部分使用狀態機;

英雄類:

using UnityEngine;

using System.Collections;

public enum PlayerState

{

    Idle,

    Attack,

    Jump,

}

public class Player : MonoBehaviour {

    public stateMachine m_stateMachine;

    public  Animation ani;

    public PlayerState playstate = PlayerState.Idle;

    //記錄狀態

    //控制機器

    void Start () {

        //初始化機器

        m_stateMachine = new stateMachine (new IdleSatae(0,this));

        //把所有狀態新增到字典中,用來改變狀態;

        m_stateMachine.RegisterState (new AttackSatae(1,this));

        m_stateMachine.RegisterState (new JumpSatae(2,this));

    }

    void Update () {

        if (Input.GetKey (KeyCode.A)) {

            playstate = PlayerState.Attack;

        }

        if (Input.GetKey (KeyCode.D)) {

            playstate = PlayerState.Jump;

        }

        PlayAi ();

    }

    void PlayAi()

    {

        switch (playstate) {

        case PlayerState.Idle:

            m_stateMachine.TranslateState (0);

            break;

        case PlayerState.Attack:

            m_stateMachine.TranslateState (1);

            break;

        case PlayerState.Jump:

            m_stateMachine.TranslateState (2);

            break;

        default:

            break;

        }

    }

    void LateUpdate()

    {

        m_stateMachine.FSMUpdate ();

    }

}