当前位置: 首页 > 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;拉比频率较低…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为技术领域的焦点。从智能写作到代码生成&#xff0c;LLM 的应用场景不断扩展&#xff0c;深刻改变了我们的工作和生活方式。然而&#xff0c;理解这些模型的内部…...

论文阅读:Matting by Generation

今天介绍一篇关于 matting 抠图的文章&#xff0c;抠图也算是计算机视觉里面非常经典的一个任务了。从早期的经典算法到如今的深度学习算法&#xff0c;已经有很多的工作和这个任务相关。这两年 diffusion 模型很火&#xff0c;大家又开始用 diffusion 模型做各种 CV 任务了&am…...

WEB3全栈开发——面试专业技能点P4数据库

一、mysql2 原生驱动及其连接机制 概念介绍 mysql2 是 Node.js 环境中广泛使用的 MySQL 客户端库&#xff0c;基于 mysql 库改进而来&#xff0c;具有更好的性能、Promise 支持、流式查询、二进制数据处理能力等。 主要特点&#xff1a; 支持 Promise / async-await&#xf…...

MySQL体系架构解析(三):MySQL目录与启动配置全解析

MySQL中的目录和文件 bin目录 在 MySQL 的安装目录下有一个特别重要的 bin 目录&#xff0c;这个目录下存放着许多可执行文件。与其他系统的可执行文件类似&#xff0c;这些可执行文件都是与服务器和客户端程序相关的。 启动MySQL服务器程序 在 UNIX 系统中&#xff0c;用…...