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

news2024/12/27 7:14:04

策略模式(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.coloradmin.cn/o/2253537.html

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

相关文章

你还没有将 Siri 接入GPT对话功能吗?

由于各种原因&#xff0c;国内ios用户目前无缘自带 AI 功能&#xff0c;但是这并不代表国内 ios 无法接入 AI 功能&#xff0c;接下来手把手带你为iPhone siri 接入 gpt 对话功能。 siri 接入 chatGPT 暂时还无法下载 ChatGPT app&#xff0c;或者没有账号的读者可以直接跳到…

linux运维命令

防火墙相关命令 防火墙规则查看 firewall-cmd --list-all 禁ping firewall-cmd --permanent --add-rich-rulerule protocol valueicmp drop firewall-cmd --reload 执行完以上命令后&#xff0c;通过firewall-cmd --list-all查看规则生效情况 firewall-cmd --list-all 其…

矩阵乘法        ‌‍‎‏

矩阵乘法 C语言代码C 语言代码Java语言代码Python语言代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 计算两个矩阵的乘法&#xff1a; 设有矩阵(A)为(nm)阶矩阵&#xff0c;矩阵(B)为(mk)阶矩阵&#xff0c;二者相乘得到的矩阵(C)是(…

docker更换容器存储位置

一&#xff1a;原因 今天之前在某个服务器上使用docker搭建的服务突然无法访问了&#xff0c;进入服务器查看发现服务运行正常&#xff0c;但是就是无法使用&#xff0c;然后我这边准备将docker服务重新启动下看看&#xff0c;发现docker服务无法重启&#xff0c;提示内存已满…

11.10VSCode配置 SSH连接远程服务器+免密连接教程

Jk200497 VScode通过remote ssh连接虚拟机 & 报错 过程试图写入的管道不存在&#xff08;已解决&#xff09;_连接虚拟机之后,提示管道错误,把上述路径加入到扩展中-CSDN博客 VSCode配置 SSH连接远程服务器免密连接教程

汽车EEA架构:架构的简介

1.架构的定义 汽车领域谈论的架构一词&#xff0c;来源于英文单词Architecture。在《系统架构:复杂系统的产品设计与开发》一书中对架构的定义如下:系统架构是一种概念的具象化&#xff0c;是物理或信息功能到形式元素的分配&#xff0c;是系统之内的元素之间的关系与周边环境…

Nginx下载、安装、启动及常用命令

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

Mac快速安装 chromedriver驱动

全篇大概1200字&#xff08;含代码&#xff09;&#xff0c;建议阅读时间5分钟。 什么是chromedriver&#xff1f; ChromeDriver 充当了 Selenium WebDriver 和 Chrome 浏览器之间的桥梁&#xff0c;允许开发者通过编程控制浏览器进行自动化测试或操作。 一、下载chromedriver…

大数据项目-Django基于聚类算法实现的房屋售房数据分析及可视化系统

《[含文档PPT源码等]精品Django基于聚类算法实现的房屋售房数据分析及可视化系统》该项目含有源码、文档、PPT、配套开发软件、软件安装教程课程答疑等&#xff01; 数据库管理工具&#xff1a;phpstudy/Navicat或者phpstudy/sqlyog 后台管理系统涉及技术&#xff1a; 后台使…

2024前端框架年度总结报告(二):新生qwik+solid和次新生svelte+Astro对比 -各自盯着前端的哪些个痛点 - 前端的区域发展差异

引言 2024年&#xff0c;前端开发依然是技术领域的热点之一。随着 Web 应用的日益复杂&#xff0c;前端框架的更新换代也加速了。尽管 React、Vue 和 Angular 老牌框架年度总结 等“老牌”框架仍然占据着主流市场&#xff0c;但一些新兴的框架在不断挑战这些“巨头”的地位&am…

MBox20边缘计算网关:氢能车间数据采集的智慧引擎

氢能作为未来能源体系的重要组成部分&#xff0c;其安全、高效、环保的特性备受瞩目。在氢能车间的日常运营中&#xff0c;数据采集是确保生产流程优化、设备稳定运行及能效提升的关键环节。然而&#xff0c;面对氢能车间复杂多变的生产环境和海量数据&#xff0c;如何实现高效…

【Linux篇】权限管理 - 用户与组权限详解

一. 什么是权限&#xff1f; 首先权限是限制人的。人 真实的人 身份角色 权限 角色 事物属性 二. 认识人–用户 Linux下的用户分为超级用户和普通用户 root :超级管理员&#xff0c;几乎不受权限的约束普通用户 :受权限的约束超级用户的命令提示符是#&#xff0c;普通用…

GPS模块/SATES-ST91Z8LR:电路搭建;直接用电脑的USB转串口进行通讯;模组上报定位数据转换地图识别的坐标手动查询地图位置

从事嵌入式单片机的工作算是符合我个人兴趣爱好的,当面对一个新的芯片我即想把芯片尽快搞懂完成项目赚钱,也想着能够把自己遇到的坑和注意事项记录下来,即方便自己后面查阅也可以分享给大家,这是一种冲动,但是这个或许并不是原厂希望的,尽管这样有可能会牺牲一些时间也有哪天原…

EasyNVR中HTTP-FLV协议无法播放怎么解决?

在科技日新月异的今天&#xff0c;摄像头作为公共安全领域的重要一环&#xff0c;其技术的不断提升正显著地改变着社会的安全格局。从最初的简单监控到如今的高清智能分析&#xff0c;我们可以对特定区域进行实时监控和记录&#xff0c;为社会的安全稳定提供了强有力的保障。 问…

linux环境GitLab服务部署安装及使用

一、GitLab介绍 GitLab是利用Ruby onRails一个开源的版本管理系统&#xff0c;实现一个自托管的Git项目仓库&#xff0c;可通过Web界面进行访问公开的或者私人项目。 二、GitLab安装 1、先安装相关依赖 yum -y install policycoreutils openssh-server openssh-clients postf…

视频码率到底是什么?详细说明

视频码率&#xff08;Video Bitrate&#xff09;是指在单位时间内&#xff08;通常是每秒&#xff09;传输或处理的视频数据量&#xff0c;用比特&#xff08;bit&#xff09;表示。它通常用来衡量视频文件的压缩程度和质量&#xff0c;码率越高&#xff0c;视频质量越好&#…

DICOM MPPS详细介绍

文章目录 前言一、常规检查业务流程二、MPPS的作用三、MPPS的原理1、MPPS与MWL2、MPPS服务过程 四、MPPS的实现步骤1、创建实例2、传递状态 五、总结 前言 医院中现有的DICOM MWL(Modality Worklist)已开始逐渐得到应用&#xff0c;借助它可以实现病人信息的自动录入&#xff0…

如何手搓一个智能激光逗猫棒

背景 最近家里的猫胖了&#xff0c;所以我就想做个逗猫棒。找了一圈市场上的智能逗猫棒&#xff0c;运行轨迹比较单一&#xff0c;互动性不足。 轨迹单一&#xff0c;活动范围有限 而我希望后续可以结合人工智能物联网&#xff0c;通过摄像头来捕捉猫的位置&#xff0c;让小…

「Mac畅玩鸿蒙与硬件42」UI互动应用篇19 - 数字键盘应用

本篇将带你实现一个数字键盘应用&#xff0c;支持用户通过点击数字键输入数字并实时更新显示内容。我们将展示如何使用按钮组件和状态管理来实现一个简洁且实用的数字键盘。 关键词 UI互动应用数字键盘按钮组件状态管理用户交互 一、功能说明 数字键盘应用将实现以下功能&…

泷羽sec-shell脚本(全) 学习笔记

声明&#xff01; 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&a…