[Unity基础]一个简单的状态机

状态机一般情况下只有两个类:状态基类以及管理状态的类。

状态机主要用于AI或者场景切换(不同场景对应的就是游戏的不同状态),当然,这只是本人的想法。


using UnityEngine;
using System.Collections;

public abstract class State {

    public int ID { set; get; }
    public Transform TargetTra { set; get; }
    public StateMachine StateMac { set; get; }

    public virtual void Enter() { }
    public virtual void Execute() { }
    public virtual void Exit() { }
}

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

public class StateMachine {

    public Dictionary<int, State> dictionary = new Dictionary<int,State>();
    public State CurrentState { set; get; }

    public State GetState(int id)
    {
        if (dictionary.ContainsKey(id))
            return dictionary[id];
        else
            return null;
    }

    public void AddState(State state)
    {
        int id = state.ID;
        if (!dictionary.ContainsKey(id))
            dictionary.Add(id, state);
    }

    public void RemoveState(int id)
    {
        if (dictionary.ContainsKey(id))
            dictionary.Remove(id);
    }

    public void InitState(int id)
    {
        if (CurrentState == null)
        {
            CurrentState = dictionary[id];
            CurrentState.Enter();
        }
    }

    public void ChangeState(int id)
    {
        if (CurrentState.ID != id)
        {
            CurrentState.Exit();
            CurrentState = dictionary[id];
            CurrentState.Enter();
        }
    }

    public void ExecuteState()
    {
        CurrentState.Execute();
    }

    public bool CheckState(int id)
    {
        return CurrentState.ID == id;
    }  
}

当编写具体的一个状态时,可以这样:

using UnityEngine;
using System.Collections;

public class RotateState : State {

    public RotateState(Transform targetTra, StateMachine sm)
    {
        ID = (int)CharacterState.rotate;
        TargetTra = targetTra;
        StateMac = sm;
    }

    public override void Enter()
    {
        base.Enter();
        Debug.Log("进入旋转状态");
        TargetTra.GetComponent<MeshRenderer>().material.color = Color.green;
    }

    public override void Execute()
    {
        base.Execute();
        TargetTra.transform.Rotate(Vector3.up);
    }

    public override void Exit()
    {
        base.Exit();
        Debug.Log("退出旋转状态");
        TargetTra.transform.localScale = new Vector3(2, 2, 2);
    }
}

测试代码:

using UnityEngine;
using System.Collections;

public class Player : MonoBehaviour {

    StateMachine stateMachine = new StateMachine();

	void Start () 
	{
        stateMachine.AddState(new RotateState(transform, stateMachine));
        stateMachine.AddState(new RunState(transform, stateMachine));
        stateMachine.InitState(((int)CharacterState.rotate));
	}
	
	void Update () 
	{
        stateMachine.ExecuteState();
	}

    void OnGUI()
    {
        if (GUILayout.Button("旋转状态"))
        {
            stateMachine.ChangeState((int)CharacterState.rotate);
        }

        if (GUILayout.Button("行走状态"))
        {
            stateMachine.ChangeState((int)CharacterState.run);
        }
    }
}


效果图:


你可能感兴趣的:(状态机)