Unity 状态模式(实例详解)

本文详细介绍了如何在Unity中使用状态模式实现角色的不同行为状态,包括基础状态切换、添加新状态、战斗状态、动画同步、状态机管理和基于条件的转换,以及多态行为和上下文类的应用。
摘要由CSDN通过智能技术生成

简介

Unity 中的状态模式(State Pattern)是一种行为设计模式,它允许一个对象在其内部状态改变时改变其行为。在游戏开发中,状态模式常用于实现角色的不同行为状态切换,例如玩家角色的行走、奔跑、跳跃、攻击等不同状态。下面将通过五个简化示例来阐述如何在Unity中实现状态模式:

示例1:基础角色状态切换

// 定义抽象状态类
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();
    }
}

示例2:添加更多角色状态

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);
}

示例3:战斗状态

public class CombatState : CharacterState
{
    // 实现战斗相关的更新逻辑,比如检测敌人、攻击等
    public override void Update()
    {
        Debug.Log("角色处于战斗状态");
        // 检查战斗是否结束,结束后切换回Idle或Run状态
        if (CombatIsOver())
        {
            character.ChangeState(new IdleState());
        }
    }
}

示例4:动画同步状态

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;
            // 其他状态对应的动画...
        }
    }
}

示例5:状态机管理器

// 为了更复杂的系统,可以创建一个专门管理状态切换和维护状态栈的类
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中应用状态模式来组织和管理不同角色状态的切换。

示例6:状态间转换的条件触发

在某些情况下,角色的状态切换可能需要基于特定的游戏事件或条件。下面展示一个基于冷却时间(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()
    {
        // 实际执行攻击逻辑,如播放动画、计算伤害等
    }
}

示例7:多态行为与上下文类

为了进一步解耦状态和角色实体,可以创建一个抽象的上下文类(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)
————————————————

​最后我们放松一下眼睛
在这里插入图片描述

  • 29
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Unity 中常用的设计模式包括以下几种: 1. 单例模式(Singleton Pattern):用于确保一个类只有一个实例,并提供全局访问点。在 Unity 中,可以使用静态变量或者脚本组件的方式实现单例模式。 2. 观察者模式(Observer Pattern):用于实现对象间的一对多依赖关系,当一个对象的状态发生变化时,所有依赖它的对象都会得到通知并自动更新。在 Unity 中,可以使用事件系统或者委托实现观察者模式。 3. 工厂模式(Factory Pattern):用于封装对象的创建过程,隐藏具体类的实例化逻辑。在 Unity 中,可以通过工厂类或者抽象工厂来创建游戏对象或其他资源。 4. 命令模式(Command Pattern):用于将请求封装成一个对象,从而可以将请求的发送者和接收者解耦。在 Unity 中,可以通过委托或者事件来实现命令模式。 5. 组合模式(Composite Pattern):用于将对象组织成树形结构,并且可以以相同的方式处理单个对象和组合对象。在 Unity 中,可以使用游戏对象的层级结构来实现组合模式。 6. 状态模式(State Pattern):用于封装对象内部状态的变化,并根据状态的变化来改变对象的行为。在 Unity 中,可以使用状态机或者策略模式来实现状态模式。 这些设计模式可以帮助开发者更好地组织和管理 Unity 项目中的代码,提高代码的可维护性和可扩展性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极致人生-010

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值