游戏框架之状态机(一)
来源:互联网 发布:淘宝网男装夏装新款 编辑:程序博客网 时间:2024/06/06 07:04
近期可能会更新多一点博客更新。
或许是这个样子,毕竟我是很懒的人,能在笔记本上做笔记的事情,我是从来不会再博客上留下痕迹的。
但涉及的框架知识,肯定要经常会回顾与更改,索性就拿上博客做为一个记录。
以后再要去更改的时候也方便一点。
作为进阶,当然是在参考了成熟的游戏框架之后所具有的新的想法。
所代表的实际意义不明,但起码能给与没有框架之说的项目一个更好的开发思路。
这里不提及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的控制,角色的状态机 等等。
只为抛砖引玉!
0 0
- 游戏框架之状态机(一)
- 基于状态机的游戏框架
- 系统设计之 状态机(一)
- 技术系列之 状态机(一)
- 技术系列之 状态机(一)
- 【原创】技术系列之 状态机(一)
- Memcached源码分析之状态机(一)
- 状态机(一)
- 做游戏长知识------基于行为树与状态机的游戏AI(一)
- UI游戏框架(一)
- 游戏角色并行状态机之boost::msm
- 跑酷游戏 之 状态机的理解
- 游戏状态机
- 游戏状态机
- Unity3D 游戏引擎之构建游戏框架与导出IOS项目(一)
- Unity3D 游戏引擎之构建游戏框架与导出IOS项目(一)
- Unity3D游戏引擎之构建游戏框架与导出IOS项目(一)
- Unity3D For iPhone游戏引擎之构建游戏框架与导出IOS项目(一)
- mtd-utils
- hadoop自定义输出文件名
- 关于Xilium.CefGlue(CEF3) 加载mp4格式失败
- Selenium 的基本了解以及Selenium IDE插件的知识点
- Java中关于OOM的场景及解决方法
- 游戏框架之状态机(一)
- GreenDao 使用方法
- Maven学习
- 抽象类和抽象方法 abstract类和abstract方法
- Pipeline System - Shader Reflection
- java Relative Path and absolute
- Service和IntentService区别
- 前端常用插件
- 用java实现视频截帧的方法