<>状态模式
在状态模式中,类的行为是基于它的状态改变的。这种类型的设计模式属于行为模式。
我们通过创建一个对象来随着状态的改变而进行不同的行为。
<>意图
允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。主要用来解决:对象的行为依赖于它的状态,并且可以根据它的状态改变而改变它的行为。
<>需求描述:
我们在游戏中控制一个角色,我们需要操作键盘,按下不同的键来改变当前角色的状态,比如控制角色奔跑、跳跃、下蹲、等等。各种状态之间存在这样的关联。默认状态为
Idle,(A->B表示由A状态可以变换到B状态)Idle->Jump、Idle->Run、Idle->Squat】、【Jump->Idle】、【Run->Jump、Run->Idle、Run->Squat】、【Squat->Idle】
。
<>状态模式的结构
* 抽象状态角色:提供一个接口,用于封装特定状态对应的行为。
* 具体状态角色:实现抽象状态角色对应的行为。
* 控制器上下文:维护当前状态,并提供触发相应状态的条件;比如:不同的键盘输入,切换不同的动画状态。
首先,定义抽象基类如下:
using System.Collections; using System.Collections.Generic; using UnityEngine;
using System; public abstract class BaseState{ public abstract void Handle(
PlayerController playerController); }
实现具体的角色状态类如下:
* Idle状态 using System.Collections; using System.Collections.Generic; using
UnityEngine; public class IdleState : BaseState { public IdleState () { } public
override void Handle (PlayerController playerController) { Debug.Log ("我在Idle");
OnEnter(playerController); } private void OnEnter (PlayerController
playerController) { playerController._currentState = this; playerController.
playerState= PlayerState.Idle; Debug.Log ("现在的状态是:" + playerController.
_currentState); } }
* Jump状态 using System.Collections; using System.Collections.Generic; using
UnityEngine; public class JumpState : BaseState { public JumpState() { } public
override void Handle (PlayerController playerController) { Debug.Log ("我在Jump");
OnEnter(playerController); } private void OnEnter (PlayerController
playerController) { playerController._currentState = this; playerController.
playerState=PlayerState.Jump; Debug.Log ("现在的状态是:" + playerController.
_currentState); } }
* Run状态 using System.Collections; using System.Collections.Generic; using
UnityEngine; public class RunState : BaseState { public RunState() { } public
override void Handle(PlayerController playerController) { Debug.Log("我Run");
OnEnter(playerController); } private void OnEnter(PlayerController
playerController) { playerController._currentState=this; playerController.
playerState=PlayerState.Run; Debug.Log("现在的状态是:"+playerController._currentState)
; } }
* Squat状态 using System.Collections; using System.Collections.Generic; using
UnityEngine; public class SquatState : BaseState { public SquatState () { }
public override void Handle (PlayerController playerController) { Debug.Log (
"我在Squat"); OnEnter(playerController); } private void OnEnter (PlayerController
playerController) { playerController._currentState = this; playerController.
playerState=PlayerState.Squat; Debug.Log ("现在的状态是:" + playerController.
_currentState); } }
* 控制器上下文实现: using System.Collections; using System.Collections.Generic; using
UnityEngine; public enum PlayerState { Idle, //站立状态 Jump, //跳跃状态 Run, //奔跑状态
Squat//下蹲状态 } public class PlayerController : MonoBehaviour { public BaseState
_currentState; public PlayerState playerState; private BaseState idleState;
private BaseState jumpState; private BaseState runState; private BaseState
squatState; void Start () { //默认的状态为Idle状态 idleState = new IdleState ();
jumpState= new JumpState (); runState = new RunState (); squatState = new
SquatState (); _currentState = new IdleState (); playerState = PlayerState.Idle;
} void Update () { switch (playerState) { case PlayerState.Idle: if (Input.
GetKeyDown(KeyCode.Space)) { _currentState = jumpState; _currentState.Handle (
this); } if (Input.GetKeyDown (KeyCode.LeftControl)) { _currentState =
squatState; _currentState.Handle (this); } if (Input.GetAxis ("Horizontal") != 0
) { _currentState = runState; _currentState.Handle (this); } break; case
PlayerState.Jump: if (!Input.GetKey (KeyCode.Space)) { _currentState = idleState
; _currentState.Handle (this); } break; case PlayerState.Run: if (Input.
GetKeyDown(KeyCode.Space)) { _currentState = jumpState; _currentState.Handle (
this); } if (Input.GetKeyDown (KeyCode.LeftControl)) { _currentState =
squatState; _currentState.Handle (this); } if (Input.GetAxis ("Horizontal") == 0
) { _currentState = idleState; _currentState.Handle (this); } break; case
PlayerState.Squat: if (!Input.GetKey (KeyCode.LeftControl)) { _currentState =
idleState; _currentState.Handle (this); } break; } } }
扫码关注获取完整Demo:
热门工具 换一换