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

Unity 设计模式-策略模式(Strategy Pattern)详解

策略模式(Strategy Pattern)是一种行为型设计模式,定义了一系列算法,并将每种算法封装到独立的类中,使得它们可以互相替换。策略模式让算法可以在不影响客户端的情况下独立变化,客户端通过与这些策略对象进行交互来执行不同的行为。

在策略模式中,核心思想是将算法的定义和使用分离,使得不同的策略(算法)可以灵活地切换,符合面向对象设计中的开闭原则,即对扩展开放、对修改关闭。

策略模式的结构

  • 策略接口(Strategy Interface):定义所有策略的共同行为,这通常是一个抽象类或接口。
  • 具体策略类(Concrete Strategy):实现策略接口的具体算法。
  • 上下文类(Context Class):维护对某个策略对象的引用,并提供对客户端的接口,允许客户端调用策略算法。

适用场景

  • 避免使用难以维护的多重条件选择语句
  • 当策略中有较为复杂的数据结构或者算法不需要暴露在客户端或者其他时。

在 Unity 中使用 策略模式

在 Unity 中使用策略模式的一个典型应用场景是为游戏角色定义不同的移动方式,例如:走路、跑步、跳跃等。在游戏开发中,不同的角色可能有不同的移动方式。通过策略模式,我们可以将这些不同的移动逻辑封装到独立的策略类中,并动态切换角色的移动方式。

1、通过策略模式实现角色的移动

 (1) 定义策略接口 

首先定义一个策略接口 IMoveStrategy,它规定所有移动策略都必须实现一个 Move() 方法。

public interface IMoveStrategy
{void Move(Transform characterTransform);
}

(2) 定义具体策略类 

创建几个具体的移动策略类 WalkStrategyRunStrategy 和 JumpStrategy,分别实现不同的移动行为。

using UnityEngine;// 走路策略
public class WalkStrategy : IMoveStrategy
{public void Move(Transform characterTransform){characterTransform.Translate(Vector3.forward * 2f * Time.deltaTime);Debug.Log("Character is walking.");}
}// 跑步策略
public class RunStrategy : IMoveStrategy
{public void Move(Transform characterTransform){characterTransform.Translate(Vector3.forward * 5f * Time.deltaTime);Debug.Log("Character is running.");}
}// 跳跃策略
public class JumpStrategy : IMoveStrategy
{public void Move(Transform characterTransform){characterTransform.Translate(Vector3.up * 5f * Time.deltaTime);Debug.Log("Character is jumping.");}
}

(3) 定义上下文类

Character 类作为上下文类,负责维护当前的移动策略,并提供方法来设置不同的移动策略和执行移动操作。

using UnityEngine;public class Character : MonoBehaviour
{private IMoveStrategy moveStrategy;// 设置移动策略public void SetMoveStrategy(IMoveStrategy strategy){moveStrategy = strategy;}// 执行移动public void PerformMove(){if (moveStrategy != null){moveStrategy.Move(transform);}else{Debug.LogWarning("Move strategy not set!");}}
}

(4) 客户端代码

在 GameController 中,我们实例化角色,并动态设置和切换移动策略。

using UnityEngine;public class GameController : MonoBehaviour
{private Character character;void Start(){// 创建角色character = gameObject.AddComponent<Character>();// 初始化为走路策略character.SetMoveStrategy(new WalkStrategy());}void Update(){// 执行移动character.PerformMove();// 根据输入切换策略if (Input.GetKeyDown(KeyCode.W)){character.SetMoveStrategy(new WalkStrategy());}else if (Input.GetKeyDown(KeyCode.R)){character.SetMoveStrategy(new RunStrategy());}else if (Input.GetKeyDown(KeyCode.Space)){character.SetMoveStrategy(new JumpStrategy());}}
}

示例解释

  • WalkStrategy:角色以较慢的速度向前移动,模拟走路的行为。
  • RunStrategy:角色以较快的速度向前移动,模拟跑步的行为。
  • JumpStrategy:角色向上跳跃,模拟跳跃的行为。

在 GameController 中,使用键盘输入(W 键、R 键和空格键)来动态切换角色的移动策略。按下相应的键后,角色将切换到走路、跑步或跳跃模式。

通过策略模式,角色的移动方式可以灵活切换,而不需要修改任何核心代码。

策略模式 在 Unity 中的优势是可以动态切换角色行为,如移动、攻击等。通过将不同的移动方式封装到独立的类中,我们可以更方便地扩展系统,并根据游戏需求随时切换策略。

2、通过策略模式实现修改图片的颜色

(1)定义策略接口

首先定义一个抽象类或接口ChangeColor,并且声明一个image参数和ExChangeColor的虚方法

using UnityEngine.UI;
public abstract class ChangeColor 
{public Image img;public virtual void ExChangeColor() { }
}

(2)定义具体策略类

然后创建几个具体的策略类,ChangeColor和ChangeBlue,分别用来改变不同颜色

//修改图片颜色为红色
using UnityEngine;
public class ChangeRed : ChangeColor
{public override void ExChangeColor(){img.color = Color.red;}
}-------------------
//修改图片颜色为蓝色
using UnityEngine;
public class ChangeBlue : ChangeColor
{public override void ExChangeColor(){img.color = Color.blue;}
}

(3)定义上下文类

维护对strategy 对象的引用,并提供方法来设置不同的操作

using UnityEngine.UI;
public class StategyContext 
{ChangeColor strategy;public StategyContext(ChangeColor strategy,Image img){this.strategy = strategy;this.strategy.img = img;}public void StategyContextInterface(){strategy.ExChangeColor();}
}

(4)客户端代码

在 StategyManager 中,我们实例化角色,并动态设置和切换移动策略。

using UnityEngine.UI;
public class StategyManager : MonoBehaviour
{[SerializeField] private Image img;StategyContext stategyContext;void Update(){if (Input.GetKeyDown(KeyCode.R)){stategyContext = new StategyContext(new ChangeRed(), img);stategyContext.StategyContextInterface();}if (Input.GetKeyDown(KeyCode.B)){stategyContext = new StategyContext(new ChangeBlue(), img);stategyContext.StategyContextInterface();}}
}

今天是2024年12月4日

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

你的对手在看书

你的仇人在磨刀

你的闺蜜在减肥

隔壁的老王在练腰

而你在干嘛?

相关文章:

Unity 设计模式-策略模式(Strategy Pattern)详解

策略模式&#xff08;Strategy Pattern&#xff09;是一种行为型设计模式&#xff0c;定义了一系列算法&#xff0c;并将每种算法封装到独立的类中&#xff0c;使得它们可以互相替换。策略模式让算法可以在不影响客户端的情况下独立变化&#xff0c;客户端通过与这些策略对象进…...

【Maven系列】深入解析 Maven 常用命令

前言 在当今的软件开发过程中&#xff0c;项目管理是至关重要的一环。项目管理包括了项目构建、依赖管理以及发布部署等诸多方面。而在Java生态系统中&#xff0c;Maven已经成为了最受欢迎的项目管理工具之一。Maven 是一套用于构建、依赖管理和项目管理的工具&#xff0c;主要…...

微信小程序之简单的数据中心管理平台(1)

微信小程序之简单的数据中心管理平台&#xff08;1&#xff09; 引言 随着微信小程序的广泛应用&#xff0c;越来越多的企业开始探索如何利用这一技术开发高效、便捷的管理平台。数据中心管理作为信息化建设的重要组成部分&#xff0c;需要一个灵活、可扩展的界面来实现资源的…...

sqlmap --os-shell的原理(MySQL,MSSQL,PostgreSQL,Oracle,SQLite)

1. MySQL 条件 数据库用户需要具备高权限&#xff08;如 FILE 权限&#xff09;。数据库服务运行用户需要对目标目录有写权限。Web 服务器有可写目录&#xff0c;且支持执行上传的脚本&#xff08;如 PHP、JSP 等&#xff09;。 原理 利用 MySQL 的 SELECT ... INTO OUTFIL…...

2024年认证杯SPSSPRO杯数学建模C题(第一阶段)云中的海盐解题全过程文档及程序

2024年认证杯SPSSPRO杯数学建模 C题 云中的海盐 原题再现&#xff1a; 巴黎气候协定提出的目标是&#xff1a;在2100年前&#xff0c;把全球平均气温相对于工业革命以前的气温升幅控制在不超过2摄氏度的水平&#xff0c;并为1.5摄氏度而努力。但事实上&#xff0c;许多之前的…...

三维扫描检测在汽车制造中的应用

三维扫描&#xff0c;通过先进三维扫描技术获取产品和物体的形面三维数据&#xff0c;建立实物的三维图档&#xff0c;满足各种实物3D模型数据获取、三维数字化展示、3D多媒体开发、三维数字化存档、逆向设计、产品开发、直接3D打印制造或辅助加工制造等一系列的应用。 三维扫描…...

【NoSQL数据库】Hbase基本操作——数据库表的增删改查

目录 一、Hbase原理 二、HBase数据库操作 三、遇到的问题和解决方法 一、Hbase原理 HBase的数据模型&#xff1a; 行键 时间戳 列族&#xff1a;contents 列族&#xff1a;anchor 列族&#xff1a;mime “com.cnn.www” T9 Achor:cnnsi.com”CNN” T8 Achor:…...

【C++】格式化输出详解:掌握 cout 的进阶用法

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;格式化输出的理论概述&#x1f4af;控制输出宽度和填充字符setw 操作符setfill 操作符 &#x1f4af;控制浮点数的显示格式fixed 与 scientificsetprecision &#x1f4af;…...

设计模式学习思路二

设计模式的学习思路_设计模式必须按顺序进行吗-CSDN博客 以下是一些方法和思路可以帮助你更清晰地识别使用了哪种设计模式。 1. 确定模式时的思考步骤 以下是分析代码时&#xff0c;你可以遵循的一些思路和步骤&#xff0c;帮助你识别可能使用的设计模式&#xff1a; a. 识别…...

什么是等级保护

1.为什么要实施等级保护: •国家信息安全形势严峻(敌对势力),针对基础信息系统的违法犯罪持续上升(网上诈骗、入侵、网上盗窃) •维护国家安全的需求(基础信息网络【互联网、电信网、广电网】及重要信息系统【银行、铁路、电力、海关】已经成为国家的关键基础设施) •信息安全是…...

k8s api对象,CRD

在Kubernetes项目中&#xff0c;一个API对象在Etcd里的完整资源路径&#xff0c;是由&#xff1a;Group&#xff08;API组&#xff09;、Version&#xff08;API版本&#xff09;和Resource&#xff08;API资源类型&#xff09;三个部分组成 apiVersion: batch/v2alpha1 kind:…...

【C++指南】C++内存管理 深度解析

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《C指南》 期待您的关注 目录 引言 一、C 内存管理概述 二、C内存区域划分 三、C 内存管理方式 &#x1f343;1.自动内存管理…...

C++小碗菜之二:软件单元测试

“没有测试的代码重构不能称之为重构&#xff0c;它仅仅是垃圾代码的到处移动” ——Corey Haines 目录 前言 什么是单元测试&#xff1f; 单元测试的组成 单元测试的命名 单元测试的独立性 Google Test 单元测试的环境配置与使用 1. Ubuntu下安装 Google Test 2. 编写…...

PyCharm+Selenium+Pytest配置小记

1、下载ChromeDriver&#xff1a; Chrome130以后的Driver下载&#xff1a; Chrome for Testing availabilityhttps://googlechromelabs.github.io/chrome-for-testing/ &#xff08;1&#xff09;查看自己Crome浏览器的版本&#xff1a;设置-->关于 Chrome&#xff1b; &…...

摩尔线程 国产显卡 MUSA 并行编程 学习笔记-2024/12/04

Learning Roadmap&#xff1a; Section 1: Intro to Parallel Programming & MUSA Deep Learning Ecosystem&#xff08;摩尔线程 国产显卡 MUSA 并行编程 学习笔记-2024/11/30-CSDN博客&#xff09;UbuntuDriverToolkitcondapytorchtorch_musa环境安装(2024/11/24-Ubunt…...

【FAQ】HarmonyOS SDK 闭源开放能力 —Remote Communication Kit

1.问题描述&#xff1a; DynamicDnsRule有没有示例&#xff1f;这个地址是怎么解析出来 https://developer.huawei.com/consumer/cn/doc/harmonyos-references/remote-communication-rcp-0000001770911890#section8160554134811 解决方案&#xff1a; ‘DynamicDnsRule’&a…...

【日常记录-Mybatis】PageHelper导致语句截断

1. 简介 PageHelper是Mybatis-Plus中的一个插件&#xff0c;主要用于实现数据库的分页查询功能。其核心原理是将传入的页码和条数赋值给一个Page对象&#xff0c;并保存到本地线程ThreadLocal中&#xff0c;接下来&#xff0c;PageHelper会进入Mybatis的拦截器环节&#xff0c;…...

随时随地掌控数据:如何使用手机APP远程访问飞牛云NAS

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

JVM 类加载器有哪些?双亲委派机制的作用是什么?如何自定义类加载器?

类加载器分类 大家好&#xff0c;我是码哥&#xff0c;可以叫我靓仔&#xff0c;《Redis 高手心法》畅销书作者。 先回顾下&#xff0c;在 Java 中&#xff0c;类的初始化分为几个阶段: 加载、链接&#xff08;包括验证、准备和解析&#xff09;和 初始化。 而 类加载器&#x…...

从基态到激发态再到里德伯态的双光子激发过程

铯原子&#xff08;Cs&#xff09;从基态6S1/2到激发态6P3/2再到里德伯态44D5/2的双光子激发过程&#xff0c; 并通过数值计算和图形化展示来研究不同失谐条件下的拉比频率、AC Stark位移差以及散射概率的变化 结果显示&#xff0c;在给定的实验参数下&#xff0c;拉比频率较低…...

终极指南:在Linux系统上安装与优化Realtek RTL8125 2.5GbE网卡驱动

终极指南&#xff1a;在Linux系统上安装与优化Realtek RTL8125 2.5GbE网卡驱动 【免费下载链接】realtek-r8125-dkms A DKMS package for easy use of Realtek r8125 driver, which supports 2.5 GbE. 项目地址: https://gitcode.com/gh_mirrors/re/realtek-r8125-dkms …...

告别HAL库延时:在STM32F103上基于CubeMX和LL库,打造更高效的SysTick延时方案

STM32F103高效延时方案&#xff1a;从HAL库到LL库的SysTick实战优化 在嵌入式开发中&#xff0c;精确的延时控制往往是项目成败的关键因素之一。许多STM32开发者最初接触的是HAL库提供的HAL_Delay()函数&#xff0c;它简单易用&#xff0c;但随着项目复杂度提升&#xff0c;特别…...

LangGraph 是什么?为什么它越来越像 AI Agent 时代的“操作系统”

文章目录一、为什么普通的“聊天式 AI”不够用了&#xff1f;1. 状态容易丢2. 流程难控制3. 执行失败后很难恢复4. 决策过程不透明二、LangGraph 到底是什么&#xff1f;1. 编排2. 运行时三、为什么很多人会说&#xff1a;LangGraph 像 Agent Server 的“操作系统”&#xff1f…...

避坑指南:iMX6ULL上RTL8723BU模块的WiFi延迟与蓝牙扫描问题分析与优化

iMX6ULL平台RTL8723BU模块WiFi/蓝牙深度调优实战 当iMX6ULL开发板遇上RTL8723BU这款高性价比的WiFi蓝牙二合一模块&#xff0c;不少开发者会发现&#xff1a;虽然基础功能能跑通&#xff0c;但实际应用中WiFi延迟飙高、蓝牙设备扫描不稳定等问题频频出现。这就像买了一辆能启动…...

你的RAR5密码有多安全?我用hashcat掩码攻击实测了一下

RAR5密码安全实测&#xff1a;从暴力破解到防御策略 当你在深夜赶工&#xff0c;把重要文件打包成加密压缩包发送给同事时&#xff0c;是否想过这个密码能撑多久&#xff1f;上周我给自己设置了一个看似安全的8位数字密码&#xff0c;结果在咖啡还没凉透前就被破解了。这不是危…...

从RTL到GDS:STA工程师的一天,如何用DC工具修复时序违例(以Setup Violation为例)

从RTL到GDS&#xff1a;STA工程师的一天&#xff0c;如何用DC工具修复时序违例&#xff08;以Setup Violation为例&#xff09; 时钟刚过上午9点&#xff0c;咖啡的香气弥漫在工位周围。作为数字后端工程师&#xff0c;我习惯在晨会前先快速扫描昨晚综合运行的日志文件。今天的…...

AI从业者的理财攻略:如何用AI技术实现被动收入

AI时代&#xff0c;软件测试从业者的新理财机遇在人工智能技术飞速发展的当下&#xff0c;软件测试行业正经历着深刻变革。传统的手工测试逐渐被自动化测试、AI驱动的测试所取代&#xff0c;这既给软件测试从业者带来了挑战&#xff0c;也创造了新的机遇。对于软件测试从业者而…...

在MMDetection 3.x中手把手复现EfficientDet的BiFPN模块(附代码逐行解读)

在MMDetection 3.x中手把手复现EfficientDet的BiFPN模块&#xff08;附代码逐行解读&#xff09; 当目标检测任务遇到多尺度物体时&#xff0c;传统特征金字塔网络&#xff08;FPN&#xff09;往往力不从心。EfficientDet提出的BiFPN&#xff08;加权双向特征金字塔网络&#x…...

手语数字人技术详解:3D 动画生成、动作自然度优化与实时渲染工程实践

一、前言&#xff1a;手语数字人是 AI 手语翻译的 “最后一公里”在国家信息无障碍政策推动下&#xff0c;AI 手语翻译已从技术实验走向大规模落地。但手语不是文字替换&#xff0c;而是身体动作、手部姿态、面部表情、口型同步的综合表达。传统手语生成普遍存在三大问题&#…...

pixi-editor

npm: zouchengxin/pixi-editor 在线地址&#xff1a;pixi-editor.pages.dev 还在为PixiJS缺少可视化编辑器而烦恼&#xff1f;试试 zouchengxin/pixi-editor&#xff01; 基于 PixiJS 构建的无限画布组件&#xff0c;支持画布平移、缩放&#xff0c;以及元素的拖动、旋转、缩…...