状态机一般情况下只有两个类:状态基类以及管理状态的类。
状态机主要用于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);
}
}
}
效果图: