unity3d状态机基础学习(二)
2017-02-03 14:39
232 查看
之前介绍了状态及状态机的概念,并且有个简单的跳转。
下面深入一点,写一个人物的普通状态、寻路状态导致的动作变化(站立状态到移动状态到骑马状态)
1、State类保持不变
2、Machine小改动了下,添加了能跳转的状态列表
3、添加了一个继承MonoBehaviour的基类FSMBase,要用到状态变化就继承这个类
4、上篇中的TestMachine改为AnimMachine,并且添加了骑马状态的情况
5、主玩家类,MainPlayer
下面深入一点,写一个人物的普通状态、寻路状态导致的动作变化(站立状态到移动状态到骑马状态)
1、State类保持不变
using UnityEngine; using System.Collections; using System.Collections.Generic; public class State { /// /// 状态名 /// public string name = ""; /// /// 构造 /// public State(string _name) { name = _name; } public State() { } public delegate void TransitionEventHandler(State _from, State _to); public delegate void OnActionHandler(State _curState); /// /// 进入时的事件 /// public TransitionEventHandler onEnter;//System.Action /// /// 退出时的事件 /// public TransitionEventHandler onExit; /// /// 在状态机Update()时候调用的更新事件 /// public OnActionHandler onAction; public virtual void Enter(State _from, State _to) { if (onEnter != null) onEnter(_from, _to); } public virtual void Excute(State _curState) { if (onAction != null) onAction(_curState); } public virtual void Exit(State _from, State _to) { if (onExit != null) onExit(_from, _to); } }
2、Machine小改动了下,添加了能跳转的状态列表
using UnityEngine; using System.Collections; public class Machine { private State curState = null; private State lastState = null; /*Update*/ public void Update () { if (curState != null) curState.Excute(curState); } /*状态改变*/ public void ChangeState (State _newState) { if (_newState == null) { Debug.LogError ("can't find this state"); return; } if (curState != null && !curState.nextStates.Contains(_newState)) { Debug.LogError("can't change to the state that curState don't contains"); return; } //触发退出状态调用Exit方法 curState.Exit(curState, _newState); //保存上一个状态 lastState = curState; //设置新状态为当前状态 curState = _newState; //m_pCurrentState.Target = m_pOwner; //进入当前状态调用Enter方法 curState.Enter(lastState, curState); } public Machine() { curState = null; lastState = null; } public Machine(State _curState) { curState = _curState; lastState = new State("init"); curState.Enter(lastState, _curState); } public void SetInitState(State _curState) { curState = _curState; lastState = new State("init"); curState.Enter(lastState, _curState); } public string GetCurStateName() { if (curState != null) { return curState.name; } return string.Empty; } /// /// 重启状态机 /// public void Restart() { } }
3、添加了一个继承MonoBehaviour的基类FSMBase,要用到状态变化就继承这个类
using UnityEngine; using System.Collections; public class FSMBase : MonoBehaviour { protected Machine stateMachine; void Start () { stateMachine = new Machine(); InitStateMachine(); } void Update() { if (stateMachine != null) stateMachine.Update(); } public virtual void Reset() { if (stateMachine != null) stateMachine.Restart(); } protected virtual void InitStateMachine() { } }
4、上篇中的TestMachine改为AnimMachine,并且添加了骑马状态的情况
using UnityEngine; using System.Collections; public class AnimMachine : FSMBase { protected State moveState = null; protected State idleState = null; protected State attackState = null; protected State rideState = null; protected override void InitStateMachine() { base.InitStateMachine(); idleState = new State("idle"); idleState.onEnter = EnterIdle; idleState.onExit = ExitIdle; idleState.onAction = ExcuteIdle; moveState = new State("move"); moveState.onEnter = EnterMove; moveState.onExit = ExitMove; moveState.onAction = ExcuteMove; attackState = new State("attack"); attackState.onEnter = EnterAttack; attackState.onExit = ExitAttack; attackState.onAction = ExcuteAttack; rideState = new State("ride"); rideState.onEnter = EnterRide; rideState.onExit = ExitRide; rideState.onAction = ExcuteRide; idleState.nextStates.Add(moveState); idleState.nextStates.Add(attackState); idleState.nextStates.Add(rideState); moveState.nextStates.Add(idleState); moveState.nextStates.Add(attackState); moveState.nextStates.Add(rideState); attackState.nextStates.Add(idleState); attackState.nextStates.Add(moveState); rideState.nextStates.Add(idleState); stateMachine.SetInitState(idleState); } void EnterIdle(State _from, State _to) { Debug.Log("EnterIdle _from:" + _from.name); } void ExitIdle(State _from, State _to) { Debug.Log("ExitIdle _to:" + _to.name); } void ExcuteIdle(State _curState) { } void EnterMove(State _from, State _to) { Debug.Log("EnterMove _from:" + _from.name); } void ExitMove(State _from, State _to) { Debug.Log("ExitMove _to:" + _to.name); } void ExcuteMove(State _curState) { } void EnterAttack(State _from, State _to) { Debug.Log("EnterAttack _from:" + _from.name); } void ExitAttack(State _from, State _to) { Debug.Log("ExitAttack _to:" + _to.name); } void ExcuteAttack(State _curState) { } void EnterRide(State _from, State _to) { Debug.Log("EnterRide _from:" + _from.name); } void ExitRide(State _from, State _to) { Debug.Log("ExitRide _to:" + _to.name); } void ExcuteRide(State _curState) { } public void Idle() { if (stateMachine != null) stateMachine.ChangeState(idleState); } public void Move() { if (stateMachine != null) stateMachine.ChangeState(moveState); } public void Ride() { if (stateMachine != null) stateMachine.ChangeState(rideState); } }
5、主玩家类,MainPlayer
using UnityEngine; using System.Collections; public class MainPlayer : FSMBase { protected State normalState = null; protected State taskPathState = null;//任务寻路 private AnimMachine animMachaine = null; void Awake() { if (animMachaine == null) { animMachaine = gameObject.GetComponent(); } if (animMachaine == null) { animMachaine = gameObject.AddComponent(); } } protected override void InitStateMachine() { base.InitStateMachine(); normalState = new State("normal"); normalState.onEnter = EnterNormalState; normalState.onExit = ExitNormalState; normalState.onAction = ExcuteNormalState; taskPathState = new State("taskPathState"); taskPathState.onEnter = EnterTaskPathState; taskPathState.onExit = ExitTaskPathState; taskPathState.onAction = ExcuteTaskPathState; normalState.nextStates.Add(taskPathState); taskPathState.nextStates.Add(normalState); stateMachine.SetInitState(normalState); } void EnterNormalState(State _from, State _to) { Debug.Log("EnterNormalState _from:" + _from.name); animMachaine.Idle(); } void ExitNormalState(State _from, State _to) { Debug.Log("ExitNormalState _to:" + _to.name) 4000 ; } void ExcuteNormalState(State _curState) { } protected float enterTaskPathTime = 0f; protected bool isRiding = false; void EnterTaskPathState(State _from, State _to) { Debug.Log("EnterTaskPathState _from:" + _from.name); animMachaine.Move(); enterTaskPathTime = Time.time; } void ExitTaskPathState(State _from, State _to) { Debug.Log("ExitTaskPathState _to:" + _to.name); isRiding = false; } void ExcuteTaskPathState(State _curState) { if (Time.time - enterTaskPathTime > 5f && !isRiding) { animMachaine.Ride(); isRiding = true; } } void OnGUI() { if (GUILayout.Button("normal")) { if (stateMachine != null) stateMachine.ChangeState(normalState); } if (GUILayout.Button("taskPath")) { if (stateMachine != null) stateMachine.ChangeState(taskPathState); } GUILayout.Label(stateMachine != null ? stateMachine.GetCurStateName() : ""); } }
相关文章推荐
- unity3d状态机基础学习(一)
- 通过例子学习正则表达式(一)--基础知识
- Windows编程基础--窗体篇(这篇文章可能会对你学习WINDOWS编程有些帮助)
- SQL的详细语法介绍——对于学习数据库最基础知识[转]
- java基础学习感悟【转】
- 最近加入了控件开发团队,发现一些基础的东西,转发上来方便大家学习(转)
- java基础学习感悟【转】
- SQL的详细语法介绍——对于学习数据库最基础知识一
- java基础学习:常用的ant的操作
- Java IO学习基础之读写文本文件
- DOS命令初学者基础知识学习
- 计算机科学与技术学习心得之计算机理论的一个核心问题--计算数学基础(转载)
- 学习 Eclipse基础--使用links方式安装Eclipse插件
- SQL的详细语法介绍——对于学习数据库最基础知识一
- ORACLE PL/SQL 基础2 (游标的学习)
- Jave基础学习:jdbc小技巧
- jsp基础学习资料
- 为UML争吵没有意思,还是把基础打好,看"学习GoF设计模式的重要性"!
- SQL的详细语法介绍——对于学习数据库最基础知识二
- Jave基础学习:jdbc小技巧