当前位置: 首页 > news >正文

Unity 设计模式-命令模式(Command Pattern)详解

命令模式(Command Pattern)是一种行为型设计模式,它将请求封装成对象,从而使得可以使用不同的请求、队列或日志请求,以及支持可撤销的操作。命令模式通常包含四个主要角色:命令(Command)、接收者(Receiver)、请求者(Invoker)和客户端(Client)。命令对象持有请求的详细信息,而接收者则执行这些请求。

什么时候使用命令模式

  • 需要支持撤销/重做功能时:例如文本编辑器、绘图软件等需要频繁撤销和重做操作的应用。
  • 需要将请求发送者与接收者解耦时:当请求的发送者和接收者之间的依赖关系需要降低时,可以使用命令模式。
  • 需要记录请求日志时:当需要跟踪请求的历史以进行审计时,命令模式提供了一种优雅的解决方案。
  • 需要实现异步请求时:可以将请求放入队列中,并在未来的某个时间点执行。

在 Unity 中使用 命令模式

在 Unity 中实现 命令模式 的示例,我们可以创建一个简单的场景,其中玩家可以使用命令来控制一个角色的移动和跳跃。这个示例将演示如何使用命令模式来处理这些操作。

1、定义命令接口

首先,我们定义一个命令接口,描述执行命令的基本操作。

public interface ICommand
{void Execute();void Undo();
}
2、定义接收者类

接下来,我们定义一个接收者类,代表要执行命令的对象(如角色)。

using UnityEngine;public class PlayerCharacter : MonoBehaviour
{public void Move(Vector3 direction){transform.position += direction;Debug.Log($"Moved to: {transform.position}");}public void Jump(float height){transform.position += Vector3.up * height;Debug.Log($"Jumped to: {transform.position}");}
}
3、实现具体命令类

然后,我们实现具体的命令类,分别用于角色的移动和跳跃操作。

public class MoveCommand : ICommand
{private PlayerCharacter player;private Vector3 direction;public MoveCommand(PlayerCharacter player, Vector3 direction){this.player = player;this.direction = direction;}public void Execute(){player.Move(direction);}public void Undo(){player.Move(-direction); // 反向移动}
}public class JumpCommand : ICommand
{private PlayerCharacter player;private float height;public JumpCommand(PlayerCharacter player, float height){this.player = player;this.height = height;}public void Execute(){player.Jump(height);}public void Undo(){player.Move(-Vector3.up * height); // 反向跳跃}
}
4、实现请求者类

我们实现一个请求者类,用于调用命令。

using System.Collections.Generic;
using UnityEngine;public class CommandInvoker : MonoBehaviour
{private Stack<ICommand> commandHistory = new Stack<ICommand>();public void ExecuteCommand(ICommand command){command.Execute();commandHistory.Push(command);}public void UndoCommand(){if (commandHistory.Count > 0){ICommand lastCommand = commandHistory.Pop();lastCommand.Undo();}}
}
5、创建游戏管理器

最后,我们创建一个游戏管理器类,处理用户输入并执行命令。

using UnityEngine;public class GameManager : MonoBehaviour
{public PlayerCharacter playerCharacter;private CommandInvoker commandInvoker;void Start(){commandInvoker = gameObject.AddComponent<CommandInvoker>();}void Update(){if (Input.GetKeyDown(KeyCode.W)){var moveCommand = new MoveCommand(playerCharacter, Vector3.forward);commandInvoker.ExecuteCommand(moveCommand);}else if (Input.GetKeyDown(KeyCode.S)){var moveCommand = new MoveCommand(playerCharacter, Vector3.back);commandInvoker.ExecuteCommand(moveCommand);}else if (Input.GetKeyDown(KeyCode.Space)){var jumpCommand = new JumpCommand(playerCharacter, 2.0f);commandInvoker.ExecuteCommand(jumpCommand);}else if (Input.GetKeyDown(KeyCode.U)){commandInvoker.UndoCommand(); // 撤销上一个命令}}
}
6、在 Unity 中测试
  • 创建一个带有 Collider 的 Cube 作为玩家角色,并附加 PlayerCharacter 脚本。
  • 创建一个空的 GameObject,命名为 GameManager,并附加 GameManager 脚本。
  • 运行游戏,使用 W 和 S 键控制前后移动,使用 Space 键跳跃,使用 U 键撤销上一个命令。

7、示例分析
  • 命令(ICommand):定义执行和撤销的基本操作。
  • 接收者(PlayerCharacter):实现角色的具体操作。
  • 具体命令(MoveCommand 和 JumpCommand):封装角色的移动和跳跃逻辑。
  • 请求者(CommandInvoker):负责执行和撤销命令。


这个示例展示了如何在 Unity 中实现 命令模式,通过封装角色的操作为命令对象,使得用户能够灵活地控制角色,同时支持撤销操作。这种模式在需要记录和管理用户输入的场景中非常有用。

今天是2024年12月4日

重复一段毒鸡汤来勉励我和你

你的对手在看书

你的仇人在磨刀

你的闺蜜在减肥

隔壁的老王在练腰

而你在干嘛?

相关文章:

Unity 设计模式-命令模式(Command Pattern)详解

命令模式&#xff08;Command Pattern&#xff09;是一种行为型设计模式&#xff0c;它将请求封装成对象&#xff0c;从而使得可以使用不同的请求、队列或日志请求&#xff0c;以及支持可撤销的操作。命令模式通常包含四个主要角色&#xff1a;命令&#xff08;Command&#xf…...

线程信号量 Linux环境 C语言实现

既可以解决多个同类共享资源的互斥问题&#xff0c;也可以解决简易的同步问题 头文件&#xff1a;#include <semaphore.h> 类型&#xff1a;sem_t 初始化&#xff1a;int sem_init(sem_t *sem, int pshared, unsigned int value); //程序中第一次对指定信号量调用p、v操…...

karmada-descheduler

descheduler规则 karmada-descheduler 定期检测所有部署&#xff0c;通常是每2分钟一次&#xff0c;并确定目标调度集群中无法调度的副本数量。它通过调用 karmada-scheduler-estimator 来完成这个过程。如果发现无法调度的副本&#xff0c;它将通过减少 spec.clusters 的配…...

【热门主题】000075 探索嵌入式硬件设计的奥秘

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 【热…...

Android okhttp请求

下面是一个用 OkHttp 封装的 GET 请求方法&#xff0c;适用于 Android 项目。该方法包括基本的网络请求、错误处理&#xff0c;并支持通过回调返回结果。 封装 GET 请求的工具类 添加依赖 在你的 build.gradle 文件中&#xff0c;确保添加了 OkHttp 的依赖&#xff1a; imple…...

嵌入式蓝桥杯学习4 lcd移植

cubemx配置 复制前面配置过的文件 打开cubemx&#xff0c;将PB8,PB9配置为GPIO-Output。 点击GENERATE CODE. 文件移植 1.打开比赛提供的文件包&#xff0c;点击Inc文件夹 2.点击Inc文件夹。复制fonts.h和lcd.h&#xff0c;粘贴到我们自己的工程文件夹的bsp中&#xff08…...

电子应用设计方案-38:智能语音系统方案设计

智能语音系统方案设计 一、引言 智能语音系统作为一种便捷、自然的人机交互方式&#xff0c;正逐渐在各个领域得到广泛应用。本方案旨在设计一个高效、准确、功能丰富的智能语音系统。 二、系统概述 1. 系统目标 - 实现高准确率的语音识别和自然流畅的语音合成。 - 支持多种语…...

渗透测试:网络安全的深度探索

一、引言 在当今数字化时代&#xff0c;网络安全问题日益凸显。企业和组织面临着来自各种恶意攻击者的威胁&#xff0c;他们试图窃取敏感信息、破坏系统或进行其他恶意活动。渗透测试作为一种主动的安全评估方法&#xff0c;能够帮助企业发现潜在的安全漏洞&#xff0c;提高网…...

基于SpringBoot的“小区物业管理系统”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“小区物业管理系统”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能结构图 个人信息界面图 费用信息管理…...

调试android 指纹遇到的坑

Android8以后版本 一、指纹服务不能自动 指纹服务fingerprintd(biometrics fingerprintservice)&#xff0c;可以手动起来&#xff0c;但是在init.rc中无法启动。 解决办法&#xff1a; 1.抓取开机时kernel log &#xff0c;确认我们的启动指纹服务的init.rc 文件有被init.c…...

剑指offer(专项突破)---字符串

总目录&#xff1a;剑指offer&#xff08;专项突破&#xff09;---目录-CSDN博客 1.字符串的基本知识 C语言中&#xff1a; 函数名功能描述strcpy(s1, s2)将字符串s2复制到字符串s1中&#xff0c;包括结束符\0&#xff0c;要求s1有足够空间容纳s2的内容。strncpy(s1, s2, n)…...

【springboot】 多数据源实现

文章目录 1. 引言&#xff1a;多数据源的必要性和应用场景**为什么需要多数据源&#xff1f;****应用场景** 2. Spring Boot中的数据源配置2.1 默认数据源配置简介2.2 如何在Spring Boot中配置多个数据源 3. 整合MyBatis与多数据源**配置MyBatis使用多数据源****Mapper接口的数…...

多模态COGMEN详解

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…...

django 实战(python 3.x/django 3/sqlite)

要在 Python 3.x 环境中使用 Django 3.2 和 SQLite 创建一个新的 Django 项目&#xff0c;你可以按照以下步骤进行操作。这些步骤假设你已经安装了 Python 3.x 和 pip。 1. 设置虚拟环境 首先&#xff0c;建议为你的 Django 项目创建一个虚拟环境&#xff0c;以便隔离项目的依…...

图数据库 | 12、图数据库架构设计——高性能计算架构

在传统类型的数据库架构设计中&#xff0c;通常不会单独介绍计算架构&#xff0c;一切都围绕存储引擎展开&#xff0c;毕竟存储架构是基础&#xff0c;尤其是在传统的基于磁盘存储的数据库架构设计中。 类似地&#xff0c;在图数据库架构设计中&#xff0c;项目就围绕存储的方…...

Unity 利用Button 组件辅助Scroll View 滚动

实现 创建枚举类ScrollDir 以区分滚动方向。每组两个按钮负责同方向上左右/上下滚动。 Update 中实时获取Scroll View 滚动条当前位置。 if (dir.Equals(ScrollDir.vertical)) {posCurrent scroll.verticalNormalizedPosition; } else if (dir.Equals(ScrollDir.horizontal)…...

Ubuntu 安装Ansible ansible.cfg配置文件生成

安装后的ansible.cfg后的默认内容如下&#xff1a; rootlocalhost:/etc/ansible# cat ansible.cfg # Since Ansible 2.12 (core): # To generate an example config file (a "disabled" one with all default settings, commented out): # $ ansible-…...

使用PaddlePaddle实现线性回归模型

目录 ​编辑 引言 PaddlePaddle简介 线性回归模型的构建 1. 准备数据 2. 定义模型 3. 准备数据加载器 4. 定义损失函数和优化器 5. 训练模型 6. 评估模型 7. 预测 结论 引言 线性回归是统计学和机器学习中一个经典的算法&#xff0c;用于预测一个因变量&#xff0…...

MongoDB集群的介绍与搭建

MongoDB集群的介绍与搭建 一.MongoDB集群的介绍 注意&#xff1a;Mongodb是一个比较流行的NoSQL数据库&#xff0c;它的存储方式是文档式存储&#xff0c;并不是Key-Value形式&#xff1b; 1.1集群的优势和特性 MongoDB集群的优势主要体现在以下几个方面&#xff1a; (1)高…...

PhpStorm配置Laravel

本文是2024最新的通过phpstorm创建laravel项目 1.下载phpstorm 2.检查本电脑的环境phpcomposer 显示图标就是安装成功了&#xff0c;不会安装的百度自行安装 3.安装完后&#xff0c;自行创建一个空目录不要有中文&#xff0c;然后运行cmd 输入以下命令&#xff0c;即可创建…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...