FSM 代码
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public delegate void MyDelegate();
public class FSM<T>
{
//用于存储所有实现状态的方法;
private Dictionary<T, MyDelegate> mAllStatesArr;
//当前状态,对应mAllStatesArr的下标;
public T mCurrentStates;
public FSM(T defaultState)
{
//初始化
mAllStatesArr = new Dictionary<T, MyDelegate>();
mCurrentStates = defaultState;
}
//添加状态
public void _FSMAddListener(T state, MyDelegate doing)
{
//判断空和去重
if (doing != null && !mAllStatesArr.ContainsKey(state))
mAllStatesArr.Add(state, doing);
}
private MyDelegate mThisState;
//每帧更新
public void Update()
{
//执行状态
//检测是否存在此状态
if (mAllStatesArr.ContainsKey(mCurrentStates))
{
mThisState = mAllStatesArr[mCurrentStates];
//检测回调是否为空
if (mThisState != null)
mThisState();
}
}
}
使用 代码
using UnityEngine;
using System.Collections;
public class Cube : MonoBehaviour
{
public enum mStates
{
Idle = 0,
Move
}
private FSM<mStates> mFsm;
private MeshRenderer mCubeMesh;
private float mTime;
private float mContinueTime;
private float mMoveSpeed;
void Awake()
{
mFsm = new FSM<mStates>(mStates.Idle);
mFsm._FSMAddListener(mStates.Idle, _IdleAndChangeColors);
mFsm._FSMAddListener(mStates.Move, _MoveAndChangeColors);
mCubeMesh = this.GetComponent<MeshRenderer>();
}
void Start()
{
mTime = 0;
mContinueTime = 0.05f;
mMoveSpeed = 5;
}
void Update()
{
mFsm.Update();
}
private void _IdleAndChangeColors()
{
if (mTime < mContinueTime)
mCubeMesh.material.color = new Color(1, 1, 0, 1);
else
{
mCubeMesh.material.color = new Color(1, 0.5f, 0, 1);
if (mTime > mContinueTime * 2)
mTime = 0;
}
mTime += Time.deltaTime;
if (Input.GetAxis("Horizontal") != 0 || Input.GetAxis("Vertical") != 0)
{
mFsm.mCurrentStates = mStates.Move;
mTime = 0;
}
}
private void _MoveAndChangeColors()
{
if (Input.GetKey(KeyCode.W))
this.transform.Translate(Vector3.forward * mMoveSpeed * Time.deltaTime, Space.World);
if (Input.GetKey(KeyCode.S))
this.transform.Translate(Vector3.back * mMoveSpeed * Time.deltaTime, Space.World);
if (Input.GetKey(KeyCode.A))
this.transform.Translate(Vector3.left * mMoveSpeed * Time.deltaTime, Space.World);
if (Input.GetKey(KeyCode.D))
this.transform.Translate(Vector3.right * mMoveSpeed * Time.deltaTime, Space.World);
if (mTime < mContinueTime)
mCubeMesh.material.color = new Color(0, 0, 1, 1);
else
{
mCubeMesh.material.color = new Color(0, 0.5f, 1, 1);
if (mTime > mContinueTime * 2)
mTime = 0;
}
mTime += Time.deltaTime;
if (Input.GetAxis("Horizontal") == 0 && Input.GetAxis("Vertical") == 0)
{
mFsm.mCurrentStates = mStates.Idle;
mTime = 0;
}
}
}