unity3d 简单状态机

看了几篇文章,感觉还是看不太懂,几篇文章的写法都是不一样的。

本文参考该篇文章:

https://blog.csdn.net/poem_qianmo/article/details/52824776

以下2篇可以看下:

https://www.jianshu.com/p/ebabe7a9f61e 比较简单的一篇文章

https://blog.csdn.net/ios_song/article/details/52327417 比较简单的一篇纯理论文章

状态机有2中实现:

switch:简单状态时使用。

状态模式实现:用多态与虚函数,当有复制的状态和逻辑时使用。

本篇文章写的很差,本人还是感觉没有理解状态机,之后会再看一次,理解之后再做修改。

Switch实现如下:

using UnityEngine;
//几种不同的状态
public enum EnemyState
{
    idle,run,dead
}
//提供几种转换不同状态的方法,以及相应的行为动作
public class EnemyFSMState : MonoBehaviour {

    private EnemyState currentState;
    // Use this for initialization
    void Start () {
        currentState = EnemyState.idle;
    }

    public void ChangeState(EnemyState state)
    {
        switch (currentState)
        {
            case EnemyState.idle:
                currentState = state;
                if (state == EnemyState.run)
                {
                    print("过渡行为 idle -> run");
                    Action(EnemyState.run);
                }
                break;
            case EnemyState.run:
                currentState = state;
                if (state == EnemyState.dead)
                {
                    print("过渡行为 run -> dead");
                    Action(EnemyState.dead);
                }
                break;
            case EnemyState.dead:
                currentState = state;
                Action(EnemyState.dead);
                break;
        }
    }

    void Action(EnemyState state)
    {
        print("做出不同的动作 "+ state);
    }
    
    // Update is called once per frame
    void Update () {
        //switch (currentState)
        //{
        //    case EnemyState.idle:
        //        Action(EnemyState.idle);
        //        break;
        //    case EnemyState.run:
        //        Action(EnemyState.run);
        //        break;
        //    case EnemyState.dead:
        //        Action(EnemyState.dead);
        //        break;
        //}
    }
}

using UnityEngine;
//发出动作,触发改变状态
public class EnemyTigger : MonoBehaviour
{
    private EnemyFSMState state;
    private void Start()
    {
        state = GetComponent<EnemyFSMState>();
    }
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.J))
        {
            state.ChangeState(EnemyState.idle);
        }
        else if (Input.GetKeyDown(KeyCode.K))
        {
            state.ChangeState(EnemyState.run);
        }
        else if (Input.GetKeyDown(KeyCode.L))
        {
            state.ChangeState(EnemyState.dead);
        }
    }
}

使用状态模式实现如下:

using UnityEngine;

//几种不同的状态
public enum PlayerState
{
    idle, run, dead
}

//几种不同的状态相同行为的部分
public interface IStateAction
{
    void Action(EnemyState state);
}
//不同状态的不同行为
public class IdleState : IStateAction
{
    public void Action(EnemyState state)
    {
        Debug.Log(" idle action ");
        if (state == EnemyState.run)
        {
            Debug.Log("过渡行为 run -> idle");
        }
    }
}
//不同状态的不同行为
public class RunState : IStateAction
{
    public void Action(EnemyState state)
    {
        Debug.Log(" run action ");
        if (state == EnemyState.idle)
        {
            Debug.Log("过渡行为 idle -> run");
        }
    }
}
//不同状态的不同行为
public class DeadState : IStateAction
{
    public void Action(EnemyState state)
    {
        Debug.Log(" dead action ");
    }
}
//状态的切换
public class FSMState : MonoBehaviour
{
    private EnemyState currentState;
    // Use this for initialization
    void Start()
    {
        currentState = EnemyState.idle;
    }
    public void ChangeState(IStateAction action, EnemyState state)
    {
        action.Action(state);
    }
}

using UnityEngine;

//发出动作,触发改变状态
public class PlayerTigger : MonoBehaviour
{
    private FSMState state;
    private void Start()
    {
        state = GetComponent<FSMState>();
    }
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.J))
        {
            state.ChangeState(new IdleState(), EnemyState.run);
        }
        else if (Input.GetKeyDown(KeyCode.K))
        {
            state.ChangeState(new RunState(), EnemyState.dead);
        }
        else if (Input.GetKeyDown(KeyCode.L))
        {
            state.ChangeState(new DeadState(), EnemyState.dead);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/tran119/article/details/81194408