Unity 中的状态模式(State Pattern)是一种行为设计模式,它允许一个对象在其内部状态改变时改变其行为。在游戏开发中,状态模式常用于实现角色的不同行为状态切换,例如玩家角色的行走、奔跑、跳跃、攻击等不同状态。下面将通过五个简化示例来阐述如何在Unity中实现状态模式:
// 定义抽象状态类
public abstract class CharacterState
{
protected Character character;
public void SetCharacter(Character _character)
{
this.character = _character;
}
// 抽象方法,子类需要实现具体行为
public abstract void Update();
}
// 具体状态类:IdleState
public class IdleState : CharacterState
{
public override void Update()
{
Debug.Log("角色处于闲置状态");
// 检查是否应该转换到其他状态,如按下移动键则切换至MoveState
if (Input.GetKey(KeyCode.W))
{
character.ChangeState(new MoveState());
}
}
}
// 具体状态类:MoveState
public class MoveState : CharacterState
{
public override void Update()
{
Debug.Log("角色正在移动");
// 检查是否应返回闲置状态或切换至其他状态
if (!Input.GetKey(KeyCode.W))
{
character.ChangeState(new IdleState());
}
}
}
// 角色类持有当前状态并处理状态切换
public class Character : MonoBehaviour
{
private CharacterState currentState;
public void ChangeState(CharacterState newState)
{
if (currentState != null)
{
currentState.SetCharacter(null);
}
currentState = newState;
currentState.SetCharacter(this);
}
void Update()
{
currentState.Update();
}
}
public class JumpState : CharacterState
{
public override void Update()
{
Debug.Log("角色正在跳跃");
// 跳跃动作完成后切换回Idle或Move状态
if (IsJumpFinished())
{
character.ChangeState(currentlyOnGround ? new IdleState() : new MoveState());
}
}
}
// 初始化时设置初始状态
void Start()
{
currentState = new IdleState();
currentState.SetCharacter(this);
}
public class CombatState : CharacterState
{
// 实现战斗相关的更新逻辑,比如检测敌人、攻击等
public override void Update()
{
Debug.Log("角色处于战斗状态");
// 检查战斗是否结束,结束后切换回Idle或Run状态
if (CombatIsOver())
{
character.ChangeState(new IdleState());
}
}
}
public class AnimationState : CharacterState
{
Animator anim;
public AnimationState(Character character, Animator animator)
{
SetCharacter(character);
anim = animator;
}
public override void Update()
{
// 根据当前状态播放相应的动画
switch (GetType().Name)
{
case nameof(IdleState):
anim.Play("Idle");
break;
case nameof(MoveState):
anim.Play("Run");
break;
// 其他状态对应的动画...
}
}
}
// 为了更复杂的系统,可以创建一个专门管理状态切换和维护状态栈的类
public class StateMachine
{
Stack<CharacterState> stateStack = new Stack<CharacterState>();
public void PushState(CharacterState newState)
{
stateStack.Push(newState);
newState.SetCharacter(character);
}
public void PopState()
{
if (stateStack.Count > 0)
{
var oldState = stateStack.Pop();
oldState.SetCharacter(null);
if (stateStack.Count > 0)
{
currentState = stateStack.Peek();
currentState.SetCharacter(character);
}
}
}
// 更新调用当前栈顶状态的方法
public void Update()
{
currentState?.Update();
}
}
以上代码仅作示例,并未涵盖所有异常处理和实际项目中的细节,但足以说明如何在Unity中应用状态模式来组织和管理不同角色状态的切换。
在某些情况下,角色的状态切换可能需要基于特定的游戏事件或条件。下面展示一个基于冷却时间(Cooldown)的状态切换示例:
public class AttackState : CharacterState
{
private float attackCoolDown;
private bool canAttack;
public AttackState(float coolDownTime)
{
attackCoolDown = coolDownTime;
canAttack = true;
}
public override void Update()
{
if (canAttack && Input.GetKeyDown(KeyCode.Space))
{
Debug.Log("角色进行攻击");
// 触发攻击动作
OnAttack();
canAttack = false;
Invoke(nameof(ResetAttack), attackCoolDown);
}
}
private void ResetAttack()
{
canAttack = true;
// 攻击结束后根据情况切换至其他状态,例如Idle
character.ChangeState(new IdleState());
}
private void OnAttack()
{
// 实际执行攻击逻辑,如播放动画、计算伤害等
}
}
为了进一步解耦状态和角色实体,可以创建一个抽象的上下文类(Context),由它来持有当前状态并处理状态之间的切换:
// 抽象上下文类
public abstract class CharacterContext
{
protected CharacterState currentState;
public virtual void ChangeState(CharacterState newState)
{
currentState?.Exit();
currentState = newState;
currentState.Enter(this);
}
public abstract void Update();
// 状态进入和退出时调用的方法
public virtual void NotifyStateEnter() => currentState.Enter(this);
public virtual void NotifyStateExit() => currentState.Exit();
}
// 具体上下文类:游戏角色实体
public class Player : CharacterContext
{
// 其他游戏相关属性...
public override void Update()
{
currentState.Update();
}
// 重写以添加额外的进入/退出通知逻辑
public override void NotifyStateEnter() { ... }
public override void NotifyStateExit() { ... }
}
// 每个状态类实现Enter和Exit方法
public class WalkState : CharacterState
{
public override void Enter(CharacterContext context)
{
// 进入行走状态时的行为,比如启动行走动画
}
public override void Exit()
{
// 退出行走状态时的行为,比如停止行走动画
}
}
以上示例展示了如何通过状态模式在Unity中灵活管理角色的不同状态,并允许状态之间根据特定条件和事件平滑切换。每个具体状态类都负责自己的行为逻辑,而上下文类则统一管理这些状态的切换。
python推荐学习汇总连接:
50个开发必备的Python经典脚本(1-10)
50个开发必备的Python经典脚本(11-20)
50个开发必备的Python经典脚本(21-30)
50个开发必备的Python经典脚本(31-40)
50个开发必备的Python经典脚本(41-50)
————————————————
最后我们放松一下眼睛