【Unity】RPG2D龙城纷争(四)要诀、要诀数据集
更新日期:2024年6月20日。
项目源码:第五章发布(正式开始游戏逻辑的章节)
索引
- 简介
- 要诀数据集(AbilityDataSet)
- 一、定义要诀数据集类
- 二、要诀属性
- 1.要诀类型
- 2.攻击距离
- 3.基础命中、暴击率
- 4.基础属性加成
- 5.要诀特效
- 三、要诀显示面板
- 要诀(Ability)
- 一、定义要诀类
- 二、角色挂载要诀
- 三、要诀栏位
- 四、要诀栏位激活
简介
上一篇有了角色
类, 这一章我们将实现要诀(也即是技能,只是这里披了另一个名字)
类,同理,要诀也应当有要诀数据集
类,用以描述要诀属性中的共用部分。
要诀数据集(AbilityDataSet)
与角色同理,比如20个士兵,当他们需要使用同一个要诀时,理应只需要持有同一个要诀数据集
即可。
一、定义要诀数据集类
首先,我们定义要诀数据集类AbilityDataSet
:
/// <summary>/// 要诀数据集/// </summary>[Serializable][CreateAssetMenu(menuName = "HTFramework/★ GameComponent/RPG2D/Ability Asset", order = 300)]public sealed class AbilityDataSet : DataSetBase{}
二、要诀属性
根据前车之鉴,我们先定义如下一系列属性:
public sealed class AbilityDataSet : DataSetBase{/// <summary>/// 要诀名称/// </summary>[Label("要诀名称")] public string Name;/// <summary>/// 要诀类型/// </summary>[Label("要诀类型")] public AbilityType Type;/// <summary>/// 攻击距离/// </summary>[Label("攻击距离"), Display("IsNoBuffProperty")] public int AttackDistance = 1;/// <summary>/// 基础命中率/// </summary>[Label("基础命中率"), Display("IsAttackProperty")] public int BaseHitRate = 100;/// <summary>/// 基础暴击率/// </summary>[Label("基础暴击率"), Display("IsAttackProperty")] public int BaseCriticalRate = 100;/// <summary>/// 速度加成/// </summary>[Label("速度加成"), Display("IsBuffProperty")] public int AddedSpeed;/// <summary>/// 生命加成(初始值)/// </summary>[Label("生命加成(初始值)"), Display("IsBuffProperty")] public int AddedHP;/// <summary>/// 攻击加成(初始值)/// </summary>[Label("攻击加成(初始值)")] public int AddedATK;/// <summary>/// 防御加成(初始值)/// </summary>[Label("防御加成(初始值)"), Display("IsBuffProperty")] public int AddedDEF;/// <summary>/// 敏捷加成(初始值)/// </summary>[Label("敏捷加成(初始值)"), Display("IsBuffProperty")] public int AddedDEX;/// <summary>/// 会心加成(初始值)/// </summary>[Label("会心加成(初始值)"), Display("IsBuffProperty")] public int AddedCRI;/// <summary>/// 生命加成(成长值)/// </summary>[Label("生命加成(成长值)"), Display("IsBuffProperty")] public int AddedHP_Inc;/// <summary>/// 攻击加成(成长值)/// </summary>[Label("攻击加成(成长值)")] public int AddedATK_Inc;/// <summary>/// 防御加成(成长值)/// </summary>[Label("防御加成(成长值)"), Display("IsBuffProperty")] public int AddedDEF_Inc;/// <summary>/// 敏捷加成(成长值)/// </summary>[Label("敏捷加成(成长值)"), Display("IsBuffProperty")] public int AddedDEX_Inc;/// <summary>/// 会心加成(成长值)/// </summary>[Label("会心加成(成长值)"), Display("IsBuffProperty")] public int AddedCRI_Inc;/// <summary>/// 要诀描述/// </summary>[Label("要诀描述"), TextArea(2, 10)] public string Description;/// <summary>/// 要诀特效/// </summary>[Label("要诀特效"), Display("IsNoBuffProperty")] public AbilityEffect Effect;}
接下来我们强行解释。
1.要诀类型
要诀类型
可分为如下三种:
/// <summary>/// 要诀类型/// </summary>public enum AbilityType{/// <summary>/// 攻击型(攻击敌方)/// </summary>[Remark("攻击型")]Attack,/// <summary>/// 加成型(被动生效,永久提升属性)/// </summary>[Remark("加成型")]Buff,/// <summary>/// 治疗型(治疗友方)/// </summary>[Remark("治疗型")]Health}
2.攻击距离
这是一个相当重要的属性,他决定了攻击、治疗(忽略加成)
型要诀的另一个重要归类
:
攻击距离 | 归类 | 原地使用 | 移动后立即使用 |
---|---|---|---|
1 | 近程攻击、治疗要诀 | 能 | 能 |
>1 | 远程攻击、治疗要诀 | 能 | 不能 |
也即是说,角色移动后是无法立即使用远程攻击、治疗要诀
的,这避免了无脑风筝对手,此对战机制照搬第二次超级机器人大战。
3.基础命中、暴击率
基础命中率、基础暴击率为此要诀在计算命中率、暴击率
时的基础值,基础命中率、基础暴击率越高的要诀,越容易命中、暴击对手。
4.基础属性加成
加成型
要诀可提供速度、生命、攻击、防御、敏捷、会心
等基础属性的加成,同时伴有成长值,随角色等级成长,同理,速度
是不能成长的。
5.要诀特效
攻击、治疗型
要诀会在释放时播放对应的特效,这里我们使用另一个类AbilityEffect
来描述,其挂载到GameObject
上后,再将创建后的预制体引入到此处便可:
/// <summary>/// 要诀特效/// </summary>[DisallowMultipleComponent]public class AbilityEffect : HTBehaviour{/// <summary>/// 发射特效(发射时播放,可为空)/// </summary>[Label("发射特效"), SerializeField] protected PlayableDirector LaunchEffect;/// <summary>/// 飞行特效(飞行中播放,如果是近程攻击型,不需要远距离飞行,可为空)/// </summary>[Label("飞行特效"), SerializeField] protected PlayableDirector FlightEffect;/// <summary>/// 击中特效(击中时播放,可为空)/// </summary>[Label("击中特效"), SerializeField] protected PlayableDirector HitEffect;/// <summary>/// 飞行特效飞行时间/// </summary>[Label("飞行特效飞行时间"), SerializeField] protected float FlightTime = 1;/// <summary>/// 发射音效/// </summary>[Label("发射音效"), SerializeField] protected AudioClip LaunchAudio;/// <summary>/// 击中音效/// </summary>[Label("击中音效"), SerializeField] protected AudioClip HitAudio;}
这里的特效采用TimeLine(PlayableDirector)
配置。
播放特效时,应当是具备延时性的,所以我们定义播放特效
为协程方法:
public class AbilityEffect : HTBehaviour{/// <summary>/// 播放特效/// </summary>/// <param name="self">要诀所属角色</param>/// <param name="other">要诀释放的目标角色</param>public virtual IEnumerator PlayEffect(Role self, Role other){//初始所有特效不可见gameObject.SetActive(true);if (LaunchEffect != null) LaunchEffect.gameObject.SetActive(false);if (FlightEffect != null) FlightEffect.gameObject.SetActive(false);if (HitEffect != null) HitEffect.gameObject.SetActive(false);//发射特效if (LaunchEffect != null){LaunchEffect.gameObject.SetActive(true);LaunchEffect.transform.position = self.transform.position;LaunchEffect.Play();if (LaunchAudio != null) Main.m_Audio.PlayOneShoot(LaunchAudio);yield return YieldInstructioner.GetWaitForSeconds((float)LaunchEffect.duration);LaunchEffect.gameObject.SetActive(false);yield return null;}//飞行特效(飞行特效应当是连贯的,除非让飞行时间完全等于特效的播放时长)if (FlightEffect != null){FlightEffect.gameObject.SetActive(true);FlightEffect.transform.position = self.transform.position;FlightEffect.Play();FlightEffect.transform.DOMove(other.transform.position, FlightTime);yield return YieldInstructioner.GetWaitForSeconds(FlightTime);FlightEffect.gameObject.SetActive(false);yield return null;}//击中特效(击中特效应当始终播放,即便未命中敌人)if (HitEffect != null){HitEffect.gameObject.SetActive(true);HitEffect.transform.position = other.transform.position;HitEffect.Play();if (HitAudio != null) Main.m_Audio.PlayOneShoot(HitAudio);yield return YieldInstructioner.GetWaitForSeconds((float)HitEffect.duration);HitEffect.gameObject.SetActive(false);yield return null;}//直接销毁特效,由于特效分类较多,就不使用对象池缓存了,当然切换成对象池也很简单Destroy(gameObject);}}
三、要诀显示面板
在要诀数据集
中,有些属性是攻击型
特有的,有些属性又是加成型
特有的,我们如何做到在检视器面板根据要诀类型只显示对它有效的属性(毕竟全都显示太过杂乱)?
这就需要HT.Framework.Display
特性了。
比如攻击距离
这个属性,很明显只有攻击、治疗型
才有效:
/// <summary>/// 攻击距离/// </summary>[Label("攻击距离"), Display("IsNoBuffProperty")] public int AttackDistance = 1;
那么此处为其标记了Display
特性,特性指定的方法将作为此属性的显示规则,比如此处的方法IsNoBuffProperty
,根据字面意义可理解为:不是加成型要诀的属性。
而事实上它的判断规则也就是这样的:
#if UNITY_EDITOR/// <summary>/// 是否为非Buff要诀属性/// </summary>private bool IsNoBuffProperty(){return Type != AbilityType.Buff;}
#endif
Display
特性仅在编辑器生效(以避免运行时多余开销),所以IsNoBuffProperty
方法也请包含在UNITY_EDITOR
宏定义中。
那么最终,我们的要诀数据集
检视器面板显示如下:
要诀(Ability)
要诀数据集
有了,同样要使用一个要诀
类来持有它。
一、定义要诀类
/// <summary>/// 要诀/// </summary>[DisallowMultipleComponent]public class Ability : HTBehaviour{/// <summary>/// 所属的角色/// </summary>[Label("所属的角色")] public Role BelongRole;/// <summary>/// 要诀栏位/// </summary>[Label("要诀栏位")] public int Index = 1;/// <summary>/// 要诀数据集/// </summary>[Label("要诀数据集"), SerializeField] internal AbilityDataSet DataSet;}
要诀(Ability)
类应当再次被角色(Role)
类所持有,如此才能形成完备的工作链,所以Ability
必须知道它所属的角色
是谁。
目前我的想法是为角色标配8个要诀栏位,所以每个要诀必须知道自身所属的要诀栏位
。
二、角色挂载要诀
上面说了要诀
将被角色
持有,所以我们将焦点切回到Role
类,以定义一些新东西:
public class Role : HTBehaviour{/// <summary>/// 要诀(持有的8个要诀)/// </summary>[Label("要诀")] public Ability[] Abilities;}
然后,挂载要诀(Ability)
类的物体,应当是角色(Role)
类的物体的子级,如下这样:
三、要诀栏位
这8个子级物体,也即是代表了8个要诀栏位
,要诀栏位检视面板如下:
要诀栏位
持有何种要诀数据集
,便决定了此栏位成为何种要诀,如果为null,则是一个空位置,可以学习其他要诀(要诀研习系统
)。
四、要诀栏位激活
8个要诀栏位
并非一出生就都激活,不然几个1级的角色也能7、8个要诀打来打去,打得天昏地暗,而所有要诀都有了,也将降低升级带来的成就感。
所以初步定义一个要诀栏位激活规则:
- 要诀栏位1:初始激活。
- 要诀栏位2:初始激活。
- 要诀栏位3:初始激活。
- 要诀栏位4:角色20级后激活。
- 要诀栏位5:角色40级后激活。
- 要诀栏位6:角色60级后激活。
- 要诀栏位7:角色80级后激活。
- 要诀栏位8:角色100级后激活。
此规则的核心奥义是:
初始3个要诀够用,每提升20级将拥有一个新的要诀栏位,使得每多出一个要诀栏位都弥足珍贵,而在角色设计之初就可以为其赋予8个完整的要诀,只是要诀栏位未激活时,要诀是不可用的。
代码实现:
/// <summary>/// 要诀位是否激活/// </summary>[PropertyDisplay("要诀位是否激活")]public virtual bool IsActive{get{if (DataSet != null){switch (Index){case 1:case 2:case 3:return true;case 4:return BelongRole.Grade >= 20;case 5:return BelongRole.Grade >= 40;case 6:return BelongRole.Grade >= 60;case 7:return BelongRole.Grade >= 80;case 8:return BelongRole.Grade >= 100;}return false;}else{return false;}}}
好了,要诀部分暂时就这些,不过我脑海中灵光一闪,第二次机战中耳熟能详的间无
机制以及二反
机制瞬间就有了照搬的方案,我将其命名为特殊加成型要诀
,那么,期待下一次登场吧!
相关文章:

【Unity】RPG2D龙城纷争(四)要诀、要诀数据集
更新日期:2024年6月20日。 项目源码:第五章发布(正式开始游戏逻辑的章节) 索引 简介要诀数据集(AbilityDataSet)一、定义要诀数据集类二、要诀属性1.要诀类型2.攻击距离3.基础命中、暴击率4.基础属性加成5.…...

一种基于非线性滤波过程的旋转机械故障诊断方法(MATLAB)
在众多的旋转机械故障诊断方法中,包络分析,又称为共振解调技术,是目前应用最为成功的方法之一。首先,对激励引起的共振频带进行带通滤波,然后对滤波信号进行包络谱分析,通过识别包络谱中的故障相关的特征频…...

HarmonyOS Next 系列之从手机选择图片或拍照上传功能实现(五)
系列文章目录 HarmonyOS Next 系列之省市区弹窗选择器实现(一) HarmonyOS Next 系列之验证码输入组件实现(二) HarmonyOS Next 系列之底部标签栏TabBar实现(三) HarmonyOS Next 系列之HTTP请求封装和Token…...
如果xml在mapper目录下,如何扫描到xml
如果xml在mapper目录下,如何扫描到xml 项目结构 src├── main│ ├── java│ │ └── com│ │ └── bg│ │ ├── Application.java│ │ ├── domain│ │ │ └── User.java│ │ …...

什么是无限铸币攻击?它是如何运作的?
一、无限铸币攻击解释 无限铸币攻击是指攻击者操纵合约代码不断铸造超出授权供应限制的新代币。 这种黑客行为在去中心化金融 (DeFi) 协议中最为常见。这种攻击通过创建无限数量的代币来损害加密货币或代币的完整性和价值。 例如,一名黑客利用了 Paid 网络的智能…...
【Android】怎么使APP进行开机启动
项目需求 在Android系统开启之后,目标app可以在系统开机之后启动。 项目实现 使用广播的方式 首先我们要创建一个广播(这里是启动了一个Service服务) public class BootReceiver extends BroadcastReceiver {Overridepublic void onReceive(Context context, I…...

详细分析Element Plus的el-pagination基本知识(附Demo)
目录 前言1. 基本知识2. Demo3. 实战 前言 需求:从无到有做一个分页并且附带分页的导入导出增删改查等功能 前提一定是要先有分页,作为全栈玩家,先在前端部署一个分页的列表 相关后续的功能,是Java,推荐阅读&#x…...
ubuntu换镜像源方法
查看ubuntu的版本,不同的版本对应的不同的镜像源 cat /etc/issue Ubuntu 18.04.6 LTS \n \l 先备份一个,防止更改错误 cobol cp /etc/apt/sources.list /etc/apt/sources.list.backup 先进入清华源,搜索ubuntu,点击问号 点进来可以看到可以…...

python flask配置邮箱发送功能,使用flask_mail模块
🌈所属专栏:【Flask】✨作者主页: Mr.Zwq✔️个人简介:一个正在努力学技术的Python领域创作者,擅长爬虫,逆向,全栈方向,专注基础和实战分享,欢迎咨询! 您的点…...

Flask快速入门(路由、CBV、请求和响应、session)
Flask快速入门(路由、CBV、请求和响应、session) 目录 Flask快速入门(路由、CBV、请求和响应、session)安装创建页面Debug模式快速使用Werkzeug介绍watchdog介绍快速体验 路由系统源码分析手动配置路由动态路由-转换器 Flask的CBV…...

人工智能指数报告
2024人工智能指数报告(一):研发 前言 全面分析人工智能的发展现状。 从2017年开始,斯坦福大学人工智能研究所(HAI)每年都会发布一份人工智能的研究报告,人工智能指数报告(AII&…...

聊聊 Mybatis 动态 SQL
这篇文章,我们聊聊 Mybatis 动态 SQL ,以及我对于编程技巧的几点思考 ,希望对大家有所启发。 1 什么是 Mybatis 动态SQL 如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼…...

【windows|004】BIOS 介绍及不同品牌电脑和服务器进入BIOS设置的方法
🍁博主简介: 🏅云计算领域优质创作者 🏅2022年CSDN新星计划python赛道第一名 🏅2022年CSDN原力计划优质作者 🏅阿里云ACE认证高级工程师 🏅阿里云开发者社区专家博主 💊交流社…...

lvgl的应用:移植MusicPlayer(基于STM32F407)
目录 概述 1 软硬件环境 1.1 UI开发版本 1.2 MCU开发环境 1.3 注意点 2 GUI Guider开发UI 2.1 使用GUI Guider创建UI 2.2 GUI Guider编译项目和测试 2.2.1 GUI Guider编译项目 2.2.2 编译 2.3 了解GUI Guider生成代码 3 移植项目 3.1 Keil中加载代码 3.2 调用G…...

Hadoop3:MapReduce中的Shuffle机制
一、流程图 Shuffle是Map方法之后,Reduce方法之前的数据处理过程称。 二、图解说明 1、数据流向 map方法中context.write(outK, outV);开始,写入环形缓冲区,再进行分区排序,写到磁盘 reduce方法拉取磁盘上的数据,…...

从设计到实践:高速公路监控技术架构全剖析
随着高速公路网络的迅速扩展和交通流量的日益增加,高效的监控系统成为保障交通安全、提升管理效率的重要手段。本文将深入探讨高速公路监控技术架构,从设计理念到实际应用,全面解析这一关键技术的各个环节。 ### 一、系统设计理念 #### 1. 高…...
Go Context
Context 介绍 Context 代表了协程的上下文,用以在父子协程之间传递控制信号,共享变量等操作// context.Context 接口 type Context interface {// 当Context自动取消或者到了取消时间被取消后返回Deadline() (deadline time.Time, ok bool)// 当Contex…...

centOS Stream9配置NAT8网络
首先将VMware关机,添加网络适配器 启动虚拟机,查看ens192是否打开连接 安装的图形化需要查看右上角电源处网卡是否连接 最小化安装一般不会出现未连接的状态 使用ip a 查看 配置网卡文件 cd /etc/NetworkManager/system-connections/cd到当前目录下…...

Linux - 进程
一、什么是进程 首先,Linux是一个多用户多进程的操作系统,系统上可以同时运行多个进程。 进程的产生:①是在执行程序或者命令时产生的;②定时任务进程 进程的类型:前台进程/后台进程 前台进程:一个终端…...

nginx+tomcat负载均衡、动静分离群集【☆☆☆☆☆】
Nginx是一款非常优秀的HTTP服务器软件,性能比tomcat更优秀,它支持高达50 000个并发连接数,拥有强大的静态资源处理能力,运行稳定,内存、CPU等系统资源消耗非常低。目前很多大型网站都应用Nginx服务器作为后端网站程序的…...

国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
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 开发者设计的强大库ÿ…...

【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...
[特殊字符] 手撸 Redis 互斥锁那些坑
📖 手撸 Redis 互斥锁那些坑 最近搞业务遇到高并发下同一个 key 的互斥操作,想实现分布式环境下的互斥锁。于是私下顺手手撸了个基于 Redis 的简单互斥锁,也顺便跟 Redisson 的 RLock 机制对比了下,记录一波,别踩我踩过…...

海云安高敏捷信创白盒SCAP入选《中国网络安全细分领域产品名录》
近日,嘶吼安全产业研究院发布《中国网络安全细分领域产品名录》,海云安高敏捷信创白盒(SCAP)成功入选软件供应链安全领域产品名录。 在数字化转型加速的今天,网络安全已成为企业生存与发展的核心基石,为了解…...
TCP/IP 网络编程 | 服务端 客户端的封装
设计模式 文章目录 设计模式一、socket.h 接口(interface)二、socket.cpp 实现(implementation)三、server.cpp 使用封装(main 函数)四、client.cpp 使用封装(main 函数)五、退出方法…...