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日

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

你的对手在看书

你的仇人在磨刀

你的闺蜜在减肥

隔壁的老王在练腰

而你在干嘛?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/33394.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

空间异质性数据分析不再复杂:地理加权回归分析、主成分分析、判别分析、分位数回归分析、线性回归等

目录 专题一 地理加权回归下的描述性统计学 专题二 地理加权主成分分析 专题三 地理加权回归 专题四 高级回归与回归之外 更多了解 在自然和社会科学领域有大量与地理或空间有关的数据&#xff0c;这一类数据一般具有严重的空间异质性&#xff0c;而通常的统计学方法并不能…

【spring mvc】全局处理请求体和响应体

目录 说明实现效果逻辑图 实现步骤创建公共处理的请求和响应的类api接口测试前端请求响应结果 扩展Response响应格式实体ResponseCode 响应状态码RSA工具类 RequestBodyAdvice 介绍使用场景 ResponseBodyAdvice 介绍使用场景 说明 由于项目中需要进行加密传输数据提高项目安全…

【计算机网络】实验8:聚合了不存在的网络导致的路由环路问题

实验 8&#xff1a;聚合了不存在的网络导致的路由环路问题 一、 实验目的 聚合了不存在的网络导致的路由环路问题。 网络故障导致的路由环路问题。 二、 实验环境 • Cisco Packet Tracer 模拟器 三、 实验内容 1、聚合了不存在的网络导致的路由环路问题 (1) 第一步&am…

【Leetcode】189.轮转数组

题目链接&#xff1a; 189.轮转数组 题目描述&#xff1a; 解题思路&#xff1a; 要想实现数组元素向右轮转k个位置&#xff0c;可是将数组三次反转来实现 以 nums [1,2,3,4,5,6,7], k 3 为例&#xff0c;最终要得到[5,6,7,1,2,3,4]: 第一次反转&#xff1a;将整个数组反转…

设计模式c++(二)

文章目录 十三、门面模式_Facade十四、代理模式_Proxy十五、适配器_Adapter十六、中介者_Mediator十七、状态模式_State十八、备忘录_Memento十九、组合模式_Composite二十、迭代器_Iterator二十一、职责链_Chain Of Resposibility二十二、命令模式_Command二十三、访问器_Vist…

shell 3 脚本参数传递与数字运算(泷羽sec)

声明 学习视频来自B站UP主 泷羽sec,如涉及侵泷羽sec权马上删除文章。 笔记只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 这节课旨在扩大自己在网络安全方面的知识面&#xff0c;了解网络安全领域的见闻&#xff0c;了…

jvm优化策略都有哪些

1. 堆内存&#xff08;Heap Memory&#xff09;优化&#xff1a; • 调整堆大小&#xff1a;通过-Xms和-Xmx参数设置JVM初始堆大小和最大堆大小&#xff0c;以确保JVM在启动时拥有足够的内存&#xff0c;并在需要时能够扩展到最大容量。 • 堆分区调整&#xff1a;调整年轻代&a…

使用ensp搭建内外互通,使用路由跨不同vlan通信。

1.网络拓扑图 2.规则 &#xff08;1&#xff09;允许 &#xff08;自己&#xff09;ping通内外网&#xff0c;内外网随便一个pc就可以. &#xff08;2&#xff09; 允许&#xff08;电信&#xff09;ping通内外网&#xff0c;内外网随便一个pc就可以 &#xff08;时间问题不做…

Flink 中维表 Join 的实现方式与优化策略

目录 一、维表介绍 二、预加载维表 &#xff08;一&#xff09;实现方式 &#xff08;二&#xff09;优缺点 &#xff08;三&#xff09;改进尝试与局限 三、使用本地缓存&#xff08;HashMap&#xff09;加载维表 &#xff08;一&#xff09;实现方式 第一版 第二版 …

详解八大排序(六)------(三路划分,自省排序,归并排序外排序)

文章目录 1. 快排之三路划分1. 1 三路划分的诞生由来1. 2 三路划分的具体思路1. 3 代码实现 2. 快排之自省排序2. 1 自省排序的目的2. 2 自省排序的思路2. 3 自省排序的实现代码 3. 归并排序外排序3. 1 外排序介绍3. 2 归并排序外排序的思路3. 3 归并排序的实现代码 1. 快排之三…

【Redis篇】 List 列表

在 Redis 中&#xff0c;List 是一种非常常见的数据类型&#xff0c;用于表示一个有序的字符串集合。与传统的链表结构类似&#xff0c;Redis 的 List 支持在两端进行高效的插入和删除操作&#xff0c;因此非常适合实现队列&#xff08;Queue&#xff09;和栈&#xff08;Stack…

计算机视觉——相机标定(Camera Calibration)

文章目录 1. 简介2. 原理3. 相机模型3.1 四大坐标系3.2 坐标系间的转换关系3.2.1 世界坐标系到相机坐标系3.2.2 相机坐标系到图像坐标系3.2.3 像素坐标系转换为图像坐标系3.2.4 世界坐标转换为像素坐标 3.3 畸变3.3.1 畸变类型3.3.1.1 径向畸变&#xff08;Radial Distortion&a…

【C++】刷题强训(day12)--删除公共字符、两个链表的第一个公共节点、mari和shiny

目录 1、删除公共字符 1.2 思路 1.3 代码实现 2、两个链表的公共节点 2.1 题目 2.2 思路 2.3 代码实现 方法一&#xff1a;对齐 方法二&#xff1a;公共端点法 3、mari和shiny 3.1 题目 3.2 思路 3.3 代码实现 刷题汇总&#xff1a;传送门&#xff01; 1、删除公共…

运费微服务和redis存热点数据

目录 运费模板微服务 接收前端发送的模板实体类 插入数据时使用的entity类对象 BaseEntity类 查询运费模板服务 新增和修改运费模块 整体流程 代码实现 运费计算 整体流程 总的代码 查找运费模板方法 计算重量方法 Redis存入热点数据 1.从nacos导入共享redis配置…

汽车IVI中控开发入门及进阶(三十六):QML调用蓝牙sdk的架构

Qt/QML本身在做GUI界面工程时,除了各种界面上的按钮、图片、工具条等元素之外,最方便的就是可以通过C++实现界面各种复杂逻辑,而实现上不可避免就需要一些外部库的支持,不管是静态库.a还是动态库.so,比如蓝牙模块。 而QML/C++启动一个蓝牙协议栈SDK作为一个进程,然后启动…

Hbase整合Mapreduce案例1 hdfs数据上传至hbase中——wordcount

目录 整合结构准备java API 编写pom.xmlMain.javaMap.javaReduce 运行 整合结构 准备 上传hdfs data.txt数据 data.txt I am wunaiieq QAQ 123456 Who I am In todays interconnected world the role of technology cannot be overstated It has revolutionized the way we …

OpenVas安装步骤及报错问题

安装步骤 1、更新系统 apt update && apt upgrade && apt dist-upgrade 2、安装openvas apt-get install openvas 3、初始化 gvm-setup 报错问题 一、安装gvm-setup报错 ERROR: The default postgresql version&#xff08;14&#xff09; is not 17 req…

高级架构二 Git基础到高级

一 Git仓库的基本概念和流程 什么是版本库&#xff1f;版本库又名仓库&#xff0c;英文名repository,你可以简单的理解一个目录&#xff0c;这个目录里面的所有文件都可以被Git管理起来&#xff0c;每个文件的修改&#xff0c;删除&#xff0c;Git都能跟踪&#xff0c;以便任何…

spark sql 环境安装,java 默认路径和 安装配置!

yum安装java 查看默认路径 update-alternatives --config java # Java 环境变量 export JAVA_HOME/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.412.b08-1.el7_9.x86_64/jreexport PATH$JAVA_HOME/bin:$PATH# Spark 环境变量 export SPARK_HOME/home/vagrant/soft/sparkexport PATH…

一文说清:Git创建仓库的方法

0 引言 本文介绍如何创建一个 Git 本地仓库&#xff0c;以及与远程仓库的关联。 1 初始化仓库&#xff08;git init&#xff09; 1.1 概述 Git 使用 git init 命令来初始化一个 Git 仓库&#xff0c;Git 的很多命令都需要在 Git 的仓库中运行&#xff0c;所以 git init 是使…