Unity 策略模式(实例详解)

文章目录

      • 简介
      • 示例1:角色攻击行为
      • 示例2:游戏内购折扣策略
      • 示例3:NPC寻路策略
      • 示例4:动画过渡策略
      • 示例5:敌人AI决策策略

简介

在Unity中使用策略模式,我们可以将不同的行为或算法封装成独立的类(策略),然后根据需要在运行时动态选择和切换这些策略。下面我将通过5个简化的代码示例来说明如何在Unity中实现策略模式。

示例1:角色攻击行为

// 定义策略接口(抽象策略类)
public abstract class AttackStrategy
{
    public abstract void ExecuteAttack(Character target);
}

// 具体策略类 - 近战攻击
public class MeleeAttack : AttackStrategy
{
    public override void ExecuteAttack(Character target)
    {
        Debug.Log($"{target.name} 使用近战攻击了 {target.Target.name}");
        // 实现具体的近战攻击逻辑...
    }
}

// 具体策略类 - 远程攻击
public class RangedAttack : AttackStrategy
{
    public override void ExecuteAttack(Character target)
    {
        Debug.Log($"{target.name} 发射了一枚远程攻击向 {target.Target.name}");
        // 实现具体的远程攻击逻辑...
    }
}

// 上下文类 - 角色
public class Character
{
    public AttackStrategy CurrentAttackStrategy { get; set; }

    public void ChangeAttackStrategy(AttackStrategy newStrategy)
    {
        CurrentAttackStrategy = newStrategy;
    }

    public void PerformAttack()
    {
        if (CurrentAttackStrategy != null)
        {
            CurrentAttackStrategy.ExecuteAttack(this);
        }
    }
}

// 使用示例
Character player = new Character();
player.CurrentAttackStrategy = new MeleeAttack(); // 设置初始攻击策略为近战
player.PerformAttack();

// 游戏进程中动态切换策略
player.ChangeAttackStrategy(new RangedAttack());
player.PerformAttack();

示例2:游戏内购折扣策略

// 抽象折扣策略
public abstract class DiscountStrategy
{
    public abstract float CalculateDiscount(float originalPrice);
}

// 具体折扣策略 - 普通价格
public class NormalDiscount : DiscountStrategy
{
    public override float CalculateDiscount(float originalPrice)
    {
        return originalPrice; // 不打折
    }
}

// 具体折扣策略 - 五折优惠
public class HalfOffDiscount : DiscountStrategy
{
    public override float CalculateDiscount(float originalPrice)
    {
        return originalPrice * 0.5f;
    }
}

// 上下文类 - 购物车
public class ShoppingCart
{
    public DiscountStrategy CurrentDiscountStrategy { get; set; }

    public float GetFinalPrice(float itemPrice)
    {
        return itemPrice * CurrentDiscountStrategy.CalculateDiscount(itemPrice);
    }

    public void SetDiscountStrategy(DiscountStrategy newDiscount)
    {
        CurrentDiscountStrategy = newDiscount;
    }
}

// 使用示例
ShoppingCart cart = new ShoppingCart();
cart.CurrentDiscountStrategy = new NormalDiscount();
float finalPrice = cart.GetFinalPrice(100); // 原价购买

cart.SetDiscountStrategy(new HalfOffDiscount());
finalPrice = cart.GetFinalPrice(100); // 半价购买

示例3:NPC寻路策略

// 抽象寻路策略
public abstract class PathfindingStrategy
{
    public abstract List<Vector3> FindPath(Vector3 start, Vector3 end);
}

// 具体寻路策略 - A*寻路
public class AStarPathfinding : PathfindingStrategy
{
    public override List<Vector3> FindPath(Vector3 start, Vector3 end)
    {
        // 实现A*算法寻找路径
        // ...
        return pathList;
    }
}

// 具体寻路策略 - Dijkstra寻路
public class DijkstraPathfinding : PathfindingStrategy
{
    public override List<Vector3> FindPath(Vector3 start, Vector3 end)
    {
        // 实现Dijkstra算法寻找路径
        // ...
        return pathList;
    }
}

// 上下文类 - NPC实体
public class NPC
{
    public PathfindingStrategy CurrentPathfindingStrategy { get; set; }

    public void MoveTo(Vector3 destination)
    {
        var path = CurrentPathfindingStrategy.FindPath(transform.position, destination);
        // 根据路径移动NPC
        // ...
    }

    public void SetPathfindingStrategy(PathfindingStrategy newPathfinding)
    {
        CurrentPathfindingStrategy = newPathfinding;
    }
}

// 使用示例
NPC npc = new NPC();
npc.CurrentPathfindingStrategy = new AStarPathfinding();
npc.MoveTo(targetPosition);

// 更改寻路策略
npc.SetPathfindingStrategy(new DijkstraPathfinding());
npc.MoveTo(anotherTargetPosition);

示例4:动画过渡策略

// 抽象动画过渡策略
public abstract class TransitionStrategy
{
    public abstract void ApplyTransition(Animator animator, string targetState);
}

// 具体动画过渡策略 - 直接切换
public class DirectTransition : TransitionStrategy
{
    public override void ApplyTransition(Animator animator, string targetState)
    {
        animator.CrossFade(targetState, 0f);
    }
}

// 具体动画过渡策略 - 平滑过渡
public class SmoothTransition : TransitionStrategy
{
    public override void ApplyTransition(Animator animator, string targetState)
    {
        animator.CrossFade(targetState, 0.5f);
    }
}

// 上下文类 - 动画控制器
public class AnimationController
{
    public TransitionStrategy CurrentTransitionStrategy { get; set; }

    public void ChangeAnimation(string stateName)
    {
        CurrentTransitionStrategy.ApplyTransition(animator, stateName);
    }

    public void SetTransitionStrategy(TransitionStrategy newStrategy)
    {
        CurrentTransitionStrategy = newStrategy;
    }
}

// 使用示例
AnimationController animCtrl = new AnimationController();
animCtrl.CurrentTransitionStrategy = new DirectTransition();
animCtrl.ChangeAnimation("Run");

// 更改过渡策略
animCtrl.SetTransitionStrategy(new SmoothTransition());
animCtrl.ChangeAnimation("Idle");

示例5:敌人AI决策策略

// 抽象AI决策策略
public abstract class AIActionStrategy
{
    public abstract void DecideAction(Enemy enemy);
}

// 具体AI决策策略 - 随机行动
public class RandomAI : AIActionStrategy
{
    public override void DecideAction(Enemy enemy)
    {
        int randomChoice = Random.Range(0, 3);
        switch (randomChoice)
        {
            case 0:
                enemy.Attack();
                break;
            case 1:
                enemy.Defend();
                break;
            case 2:
                enemy.Flee();
                break;
        }
    }
}

// 具体AI决策策略 - 精确计算行动
public class CalculatedAI : AIActionStrategy
{
    public override void DecideAction(Enemy enemy)
    {
        // 根据战场情况、玩家状态等精确计算并执行动作
        // ...
    }
}

// 上下文类 - 敌人实体
public class Enemy
{
    public AIActionStrategy CurrentAIAction { get; set; }

    public void UpdateAI()
    {
        CurrentAIAction.DecideAction(this);
    }

    public void SetAIAction(AIActionStrategy newAI)
    {
        CurrentAIAction = newAI;
    }
}

// 使用示例
Enemy enemy = new Enemy();
enemy.CurrentAIAction = new RandomAI();
enemy.UpdateAI(); // 随机执行动作

// 更改AI策略
enemy.SetAIAction(new CalculatedAI());
enemy.UpdateAI(); // 根据计算结果执行动作

以上每个示例都展示了策略模式的基本应用,在Unity中可以根据具体项目需求灵活运用这一设计模式。

python推荐学习汇总连接:
50个开发必备的Python经典脚本(1-10)

50个开发必备的Python经典脚本(11-20)

50个开发必备的Python经典脚本(21-30)

50个开发必备的Python经典脚本(31-40)

50个开发必备的Python经典脚本(41-50)
————————————————

​最后我们放松一下眼睛
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringMVC 自动配置

SpringMVC 自动配置 一、WebMvcAutoConfiguration&#xff08;SpringMVC自动配置&#xff09;二、DisPatcherServletAutoConfiguration.class&#xff08;中央调度器自动配置&#xff09;三、WebMvcConfigurationSupport&#xff08;SpringMVC组件配置类&#xff09;四、Servle…

iOS 17.4 苹果公司正在加倍投入人工智能

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

网络隔离场景下访问 Pod 网络

接着上文 VPC网络架构下的网络上数据采集 介绍 考虑一个监控系统&#xff0c;它的数据采集 Agent 是以 daemonset 形式运行在物理机上的&#xff0c;它需要采集 Pod 的各种监控信息。现在很流行的一个监控信息是通过 Prometheus 提供指标信息。 一般来说&#xff0c;daemonset …

低功耗蓝牙(BLE) 和 经典蓝牙(SPP) 的区别

低功耗蓝牙(BLE) vs 经典蓝牙(SPP) 区别项低功耗蓝牙(BLE)经典蓝牙(SPP 串行端口协议)蓝牙版本蓝牙版本 > 4.0&#xff0c;又称蓝牙低功耗、蓝牙智能经典蓝牙2.0 或更早版本&#xff0c;经典配对模式在两台蓝牙设备之间建立虚拟串口数据连接&#xff0c;提供一种简单而直接…

06.VLAN、Trunk和Hybrid配置

文章目录 一. 初识VLAN1.1. VLAN概述1.2. VLAN的优势1.3. VLAN的帧格式1.4. 接口链路类型1.5. 默认VLAN1.6. VLAN划分方式 二. 实验题2.1. 实验1&#xff1a;划分VLAN2.1.1. 实验目的2.1.2. 实验拓扑图2.1.3. 实验步骤&#xff08;1&#xff09;配置PC机的IP地址&#xff08;2&…

stable diffusion学习笔记——文生图(二)

LORA和Embeddings都可以对画面内容进行调整。目前LORA主要用来定义画面特征&#xff0c;如具体的人物&#xff0c;衣物&#xff0c;画风等。Embeddings目前主要用于反面提示词中&#xff0c;用来避免错误的画面表现。 LORA lora的全称为&#xff1a;低秩适应模型。lora的基本…

05. 交换机的基本配置

文章目录 一. 初识交换机1.1. 交换机的概述1.2. Ethernet_ll格式1.3. MAC分类1.4. 冲突域1.5. 广播域1.6. 交换机的原理1.7. 交换机的3种转发行为 二. 初识ARP2.1. ARP概述2.2. ARP报文格式2.3. ARP的分类2.4. 免费ARP的作用 三. 实验专题3.1. 实验1&#xff1a;交换机的基本原…

常用芯片学习——AMS1117芯片

AMS1117 1A 低压差线性稳压器 使用说明 AMS1117 是一款低压差线性稳压电路&#xff0c;该电路输出电流能力为1A。该系列电路包含固定输出电压版本和可调输出电压版本&#xff0c;其输出电压精度为士1.5%。为了保证芯片和电源系统的稳定性&#xff0c;XBLWAMS1117 内置热保护和…

Nulls: Nothing to Worry About

本文是文章Nulls: Nothing to Worry About的翻译笔记。 避免三值逻辑出现问题。 ISO SQL 标准中的NULL可以是任何东西&#xff0c;但不是一个值。 NULL是指示完全缺乏值的标记。 它们会导致三值逻辑&#xff0c;使用起来很混乱&#xff0c;而且这种混乱常常导致粗心的人编写返…

20240126收获

el-table比较常见的需要跳转column的场景&#xff0c;目前遇到三种&#xff0c;一种是前面列变成序号&#xff0c;用的是typeindex和&#xff1a;index来设置索引&#xff0c;第二种是变成多选&#xff0c;用的是typeselect和在table上加上select-change事件&#xff0c;第三种…

指针操作一维字符型数组和及回调函数------努力学习嵌入式的第十四天!今天的内容让人脑瓜子嗡嗡的 着重复习

总结 1.快速排序 注意&#xff1a; 第二三步并不能反过来 要想降序排列只需要加将比较的符号换一下 2.指针操作一维字符型数组 &#xff08;const&#xff09; char *s "hello"; *sH; //错误 char s[]"hello"; s[0] B char *strncpy(char *d…

掌握 Android JNI 基础

写在前面 最近在看一些底层源码&#xff0c;发现 JNI 这块还是有必要系统的看一下&#xff0c;索性就写一写博客&#xff0c;加深加深印象&#x1f37b; 本文重点聊一聊一些干货&#xff0c;避免长篇大论 JNI 概述 JNI 是什么&#xff1f; 定义&#xff1a;Java Native In…

全国网络安全行业职业技能大赛WP

word_sercet 文档被加密 查看图片的属性 在备注可以看到解压密码 解密成功 在选项里面把隐藏的文本显示出来 可以看到ffag easy_encode 得到一个bmp二维码 使用qr research 得到的密文直接放瑞士军刀 base32解码base64解码hex解码 dir_pcap 直接搜索flag 发现flag…

C++ 程序使用 OpenCV 可视化和分析两个图像之间特征点的对应关系

文章目录 代码功能源码文件编译文件 代码功能 创建图像和生成随机特征点&#xff1a; 程序首先创建两个灰度图像&#xff08;m_image_Left_BGR 和 m_image_Right_BGR&#xff09;&#xff0c;并将它们转换为彩色图像。然后&#xff0c;生成两组随机特征点&#xff08;mvKeys 和…

线段树分治总结

线段树分治总结 概念例题二分图 /【模板】线段树分治[HAOI2017] 八纵八横[FJOI2015] 火星商店问题EnvyExtending Set of PointsForced Online Queries Problem「雅礼集训 2018 Day10」贪玩蓝月BZOJ4184-shallot[bzoj4644]经典**题 概念 \qquad 线段树分治一般用来解决带有如下两…

强敌环伺:金融业信息安全威胁分析——整体态势

从早期的Zeus和其他以银行为目标的特洛伊木马程序&#xff0c;到现在的大规模分布式拒绝服务&#xff08;DDoS&#xff09;攻击&#xff0c;再到新颖的钓鱼攻击和勒索软件&#xff0c;金融服务业已成为遭遇网络犯罪威胁最严重的行业之一。金融服务业的重要性不言而喻&#xff0…

浙政钉(专有钉钉)

专有钉钉是浙政钉的测试版本&#xff0c;可在正式发布之前进行业务开发。 专有钉钉 原名政务钉钉 是高安全、强管控、灵活开放的面向大型组织专有独享的协同办公平台。支持专有云、混合云等多种方式灵活部署&#xff0c;以满足客户特定场景所需为目标&#xff0c;最大化以“平…

Docker 搭建MySQL主从复制-读写分离

一. 介绍 MySQL主从复制是一种常用的数据库高可用性解决方案&#xff0c;通过在主数据库上记录的数据变更&#xff0c;同步到一个或多个从数据库&#xff0c;实现数据的冗余备份和读写分离。在Docker环境下搭建MySQL主从复制和读写分离&#xff0c;不仅方便管理&#xff0c;还…

【干货】【常用电子元器件介绍】【电容】(二)--电容器的主要参数、测量、选择与应用

声明&#xff1a;本人水平有限&#xff0c;博客可能存在部分错误的地方&#xff0c;请广大读者谅解并向本人反馈错误。 一、 电容器的主要参数 1.1 耐压 耐压(Voltage Rating)是指电容器在电路中长期有效地工作而不被击穿所能承受的最大直流电压。对于结构、介质、容量相同的…

Linux--redhat9创建软件仓库

1.插入光盘&#xff0c;挂载镜像 模拟插入光盘: 点击:虚拟机-可移动设备-CD/DVD 设备状态全选&#xff0c;使用ISO影响文件选择当前版本镜像&#xff0c;点击确认。 2.输入: df -h 可以显示&#xff0c;默认/dev/sr0文件为光盘文件&#xff0c;挂载点为/run/media/root/镜像…
最新文章