近期可能会更新多一点博客更新。
或许是这个样子,毕竟我是很懒的人,能在笔记本上做笔记的事情,我是从来不会再博客上留下痕迹的。
但涉及的框架知识,肯定要经常会回顾与更改,索性就拿上博客做为一个记录。
以后再要去更改的时候也方便一点。
作为进阶,当然是在参考了成熟的游戏框架之后所具有的新的想法。
所代表的实际意义不明,但起码能给与没有框架之说的项目一个更好的开发思路。
这里不提及MVC等理论性大于实践性的框架,毕竟研究透彻之后才能结合unity达到一个比较好的效果,不然在此之前无实际作用。
因为unity以Component组件方式就已经算是一种框架了。
讲讲正文:
首先先要明白为什么要用这个状态机。
我的解释是UI框架,角色控制,AI等等
具体可以了解下
http://www.manew.com/thread-41889-1-1.html
他这个例子是UI整个框架切换就是用的状态机。
来看下整个思路。
首先有个IState的接口类。
有一个状态管理类StateMachine来控制状态的注册,切换,以及增删查(很像数据库有没有)
每一个状态都是一个单独的类(UI可以不用,可以用一个类注册,然后用不同的回调函数做响应)继承IState接口。
所以我们只需要控制管理类StateMachine就能实现状态机的改变。
是不是很棒,上代码
using UnityEngine;
using System.Collections;
public interface IState {
/// <summary>
/// 获取这个状态机的状态
/// </summary>
/// <returns></returns>
///
uint GetStateID();
/// <summary>
/// 进入这个状态
/// </summary>
/// <param name="machine">状态机</param>
/// <param name="PrevState">上一个状态</param>
/// <param name="param1">参数1</param>
/// <param name="param2">参数2</param>
void OnEnter(StateMachine machine ,IState PrevState ,object param1, object param2);
/// <summary>
/// 离开当前状态
/// </summary>
/// <param name="nextState">下一个进入状态</param>
/// <param name="param1">参数1</param>
/// <param name="param2">参数2</param>
void OnLeave(IState nextState, object param1, object param2);
void OnUpdate();
void OnFixedUpdate();
void OnLeteUpdate();
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class StateMachine
{
/// <summary>
/// 所有的状态集合
/// </summary>
private Dictionary<uint, IState> mStateDir = null;
/// <summary>
/// 当前状态
/// </summary>
private IState mCurrentState = null;
/// <summary>
/// 当前状态
/// </summary>
public IState CurrentState
{
get
{
return mCurrentState;
}
}
/// <summary>
/// 当前状态id
/// </summary>
public uint CurrentId
{
get
{
return mCurrentState ==null ?0:mCurrentState.GetStateID();
}
}
public StateMachine()
{
mStateDir = new Dictionary<uint, IState>();
mCurrentState = null;
}
/// <summary>
/// 注册一个状态
/// </summary>
/// <param name="state">状态对象</param>
/// <returns>成功还是失败</returns>
public bool RegisterState(IState state)
{
if(state ==null)
{
Debug.LogError("StateMachine.RegisterState state is null");
return false;
}
if(mStateDir.ContainsKey(state.GetStateID()))
{
Debug.LogError("state have this key,but stateID =" + state.GetStateID());
return false;
}
mStateDir.Add(state.GetStateID(),state);
return true;
}
/// <summary>
/// 移除一个状态
/// </summary>
/// <param name="stateId">状态Id</param>
/// <returns>当状态不存在或者状态正在运行,那么返回false</returns>
public bool RemoveState(uint stateId)
{
if(!mStateDir.ContainsKey(stateId))
{
return false;
}
if(mCurrentState != null && mCurrentState.GetStateID() ==stateId)
{
return false;
}
mStateDir.Remove(stateId);
return true;
}
/// <summary>
/// 获取一个状态
/// </summary>
/// <param name="stateId">状态id</param>
/// <returns></returns>
public IState GetStart(uint stateId)
{
IState state = null;
mStateDir.TryGetValue(stateId, out state);
return state;
}
/// <summary>
/// 停止当前状态
/// </summary>
/// <param name="param1">参数1</param>
/// <param name="param2">参数2</param>
public void StopState(object param1 ,object param2)
{
if(mCurrentState ==null)
{
return;
}
mCurrentState.OnLeave(null, param1, param2);
mCurrentState = null;
}
/// <summary>
/// 切换状态的回调
/// </summary>
public BetweenSwitchState BetweenSwitchStateCallBack = null;
/// <summary>
/// 切换状态回调委托
/// </summary>
/// <param name="from">当前状态</param>
/// <param name="to">要跳转的状态</param>
/// <param name="param1">参数1</param>
/// <param name="param2">参数2</param>
public delegate void BetweenSwitchState(IState from, IState to, object param1, object param2);
/// <summary>
/// 切换状态
/// </summary>
/// <param name="newStateId">要切换状态Id</param>
/// <param name="param1">参数1</param>
/// <param name="param2">参数2</param>
/// <returns>如果不存在这个状态或者当前状态等于要切换的状态Id,返回失败</returns>
public bool SwitchState(uint newStateId, object param1,object param2)
{
if(mCurrentState != null &&mCurrentState.GetStateID() ==newStateId)
{
return false;
}
IState newState = null;
mStateDir.TryGetValue(newStateId, out newState);
if(newState ==null)
{
return false;
}
if(mCurrentState !=null)
{
mCurrentState.OnLeave(newState, param1, param2);
}
IState oldState = mCurrentState;
mCurrentState = newState;
if(BetweenSwitchStateCallBack != null)
{
BetweenSwitchStateCallBack(oldState, mCurrentState, param1, param2);
}
newState.OnEnter(this, oldState, param1, param2);
return true;
}
/// <summary>
/// 判断当前状态是否是某个状态
/// </summary>
/// <param name="stateId"></param>
/// <returns></returns>
public bool IsInState(uint stateId)
{
return mCurrentState == null ? false : mCurrentState.GetStateID() == stateId;
}
public void OnUpdate()
{
if(mCurrentState != null)
{
mCurrentState.OnUpdate();
}
}
public void OnFixedUpdate()
{
if (mCurrentState != null)
{
mCurrentState.OnFixedUpdate();
}
}
public void OnLeteUpdate()
{
if (mCurrentState != null)
{
mCurrentState.OnLeteUpdate();
}
}
}
using UnityEngine;
using System.Collections;
public class Test : MonoBehaviour {
[HideInInspector]
public StateMachine PlayStateMachine = new StateMachine();
/// <summary>
/// 角色状态ID
/// </summary>
public enum StateType:uint
{
LeftRight=0,
UpDown=1,
}
void Awake()
{
//注册状态
PlayStateMachine.RegisterState(new LeftRightState(this));
PlayStateMachine.RegisterState(new UpDownState(this));
}
void Update()
{
PlayStateMachine.OnUpdate();
}
void FixedUpdate()
{
PlayStateMachine.OnFixedUpdate();
}
void LeteUpdate()
{
PlayStateMachine.OnLeteUpdate();
}
void OnGUI()
{
if(GUI.Button(new Rect(0,0,100,100),"leftright"))
{
//切换状态
PlayStateMachine.SwitchState((uint)StateType.LeftRight, null, null);
}
else if (GUI.Button(new Rect(100, 100, 100, 100), "updown"))
{
//切换状态
PlayStateMachine.SwitchState((uint)StateType.UpDown, null, null);
}
}
}
using UnityEngine;
using System.Collections;
public class LeftRightState : IState {
/// <summary>
/// 当前角色控制脚本引用
/// </summary>
Test mTest = null;
public LeftRightState(Test test)
{
mTest = test;
}
uint IState.GetStateID()
{
return (uint)Test.StateType.LeftRight;
}
void IState.OnEnter(StateMachine machine, IState PrevState, object param1, object param2)
{
Debug.Log("Test LeftRight OnEnter");
}
void IState.OnLeave(IState nextState, object param1, object param2)
{
Debug.Log("Test LeftRight OnLeave");
}
private bool isLeft = true;
void IState.OnUpdate()
{
if(isLeft)
{
mTest.transform.position += new UnityEngine.Vector3(-0.1f, 0, 0);
if(mTest.transform.position.x <= -1.5f)
{
isLeft = false;
}
}
else
{
mTest.transform.position += new UnityEngine.Vector3(0.1f, 0, 0);
if (mTest.transform.position.x >= 1.5f)
{
isLeft = true;
}
}
}
void IState.OnFixedUpdate()
{
}
void IState.OnLeteUpdate()
{
}
}
using UnityEngine;
using System.Collections;
public class UpDownState : IState
{
/// <summary>
/// 当前角色控制脚本引用
/// </summary>
Test mTest = null;
public UpDownState(Test test)
{
mTest = test;
}
uint IState.GetStateID()
{
return (uint)Test.StateType.UpDown;
}
void IState.OnEnter(StateMachine machine, IState PrevState, object param1, object param2)
{
Debug.Log("Test UpDown OnEnter");
}
void IState.OnLeave(IState nextState, object param1, object param2)
{
Debug.Log("Test UpDown OnLeave");
}
private bool isUp = true;
void IState.OnUpdate()
{
if(isUp)
{
mTest.transform.position += new UnityEngine.Vector3(0f, 0.1f, 0);
if (mTest.transform.position.y >= 1.5f)
{
isUp = false;
}
}
else
{
mTest.transform.position += new UnityEngine.Vector3(0f, -0.1f, 0);
if (mTest.transform.position.y <= -1.5f)
{
isUp = true;
}
}
}
void IState.OnFixedUpdate()
{
}
void IState.OnLeteUpdate()
{
}
}
总体来说 功能很简单 但是,其核心思想还是很不错的。
可以拓展为UI的控制加载,NPC AI的控制,角色的状态机 等等。
只为抛砖引玉!