帧同步BUFF功能实现¶
buff其实也是技能的一部分,和技能的区别主要在于其不是由玩家操作直接触发,而是通过技能、道具或者条件进行的一种附着施加,可以有持续附着触发逻辑的效果。并且通用技能一般只会处理基础伤害行为,而buff可以使得属性的处理更加多样。
BUFF逻辑层主要功能:¶
- 单位附着:施法者、目标、范围(比如在场景中持续存在)、子弹等。
- 延时作用:等待一段时间后再开始生效。
- 目标判定:检测敌方、友方、全体、范围等等,施加效果
- 间隔计时:在计时期间持续触发(持续性回血、DOT伤害等)。
BUFF 逻辑单元¶
BUFF的逻辑单元比技能简洁一些。只需按照:【构造->初始化->更新->反初始化】 这一套执行即可。
- 一些buff信息的缓存数据
- 构造函数:用于获取buff的信息(起源目标,作用目标,起源技能,BUFFID、特别参数等)
- LogicInit初始化函数:通过BUFFID拿配置,对BUFF进行初始化。
- LogicTick逻辑更新:进行BUFF状态转换和具体BUFF逻辑实现。
- LogicUnInit反初始化
BUFF状态转换¶
BUFF可以抽象为下面五种状态,理解下面五种状态就可以理解BUFF的功能,然后放在LogicTick处理功能就好。
五大状态: - None:BUFF完全失效,无需逻辑处理,此时可用轮询去除。 逻辑更新处理LogicTick(): - Delay:延时触发 - Start: - 通用逻辑特效挂载:获得特效,设置跟随方式,并开始BuffView的初始化。 - 通用音效挂载:有特效-特效播音乐。没有就是玩家自己播音乐。 - 处理BUFF开始单次触发的逻辑 - 判断BUFF时效(单次、限时、永久),转换到不同的分支 - Tick: - 通用击中音效播放:有目标且存在击中音频 - 制作间隔触发逻辑 - 保持计时,判断是限时还是永久最后进入不同分支 - END: - 通用特效回收:有特效、 销毁 - BUFF结束逻辑,进行资源清理和属性回调,清理结束转为None。
BUFF 表现层主要功能BuffView(特效显示)¶
继承自ViewUnit表现单元,主要做跟随、特效显示 - BuffView挂载位置:特效 - 跟随实体运动的BUFF: - 用一个空函数覆盖update逻辑:不再跟随逻辑运动,比如有些特效,始终绑在人物身上,会有一些轻微的不同步 - 初始化跟随: - 固定位置BUFF:BuffView初始化时,位置设定成自己BUFF的逻辑位置和方向。 - 跟随位置BUFF:由于表现单元初始化时已经和逻辑单元进行同步。期间可能发生位移。 - buff的Start逻辑中执行--如果不是非静态位置BUFF,先和持有者跟随单元逻辑位置再次进行同步。 - 此外,需要先将拿到跟随单元,将BuffView挂载的物体设置到自己的子节点下面,重置本地坐标和缩放。 - BUFF图标:这个就完全根据需求,有需要的BUFF单独去调用了。 - 通用函数:提供一个通用的显示函数供调用 - 倒计时:根据计时进度填Image的fillAmount就行,超时就关掉了。
BUFF 管理¶
已经开始运行的BUFF类存储在主逻辑单元的技能模块MainLogicSkill中,用一个List来作为容器。 - BUFF插入:创建buff时,需直接加入List - 逻辑执行:逻辑帧每帧轮询状态,执行LogicTick逻辑。 - 删除BUFF:轮询检测到None,触发LogicUnInit,并从容器中将BUFF移除。
被动技能(BUFF)¶
这玩意儿说是一个技能,其实就是一个或者多个存在的永久buff。 逻辑单元配置新增一个数组,用来专门存储被动BUFF,被动在单位初始化后就应该永久存在。 - 初始化时机:在技能系统初始化阶段和其他技能一起初始化。
BUFF添加流程¶
写BUFF多看看这个流程,别找来找去的了。 - 增加枚举(新BUFF) - 写Buff配置派生类:如果需要新增字段 - 设置一个BUFF配置 - 写Buff逻辑类 - 根据ID获得BUff配置:在ResSvc的GetBuffConfigByID添加,绑定ID和配置关系 - 添加Buff逻辑类 :在ResSvc的CreateBuff添加,绑定Buff枚举和Buff逻辑类关系。
全局通用BUFF¶
有些buff是全局所有角色都要调用的,甚至存在于技能系统的固定流程中,那我们直接先将ID定义到全局常量表。
1. 技能朝向索敌--【移动攻击BUFF】¶
- 全局配置:设置一个较大的BuffID如90000到Constant全局常量表中。其他如buff配置结构还是按照正常配置进行
- 触发时机:技能开始后摇了,但是技能却还处于前摇或者未开始状态(代表技能未成功释放)。如果目标是合理敌方目标就拿到移动攻击buff执行,不过
- 技能调用时机: 具体的技能等移动攻击buff逻辑移动到位后再去调用
- 移动攻击唯一性:注意这个buff不允许叠加需要先用id查一下,有的话直接把当前正在执行的结束了。
技能逻辑:Tick逻辑帧==连续检测==目标并执行逻辑。 - 找目标判距离:先拿到离自己最近的敌方目标,检测其是否在搜索距离内。是则激活 - 激活移动攻击:先设置一个bool用来判定是否激活技能。 - 无目标: 找不到最近目标,啥都不干,buff留着继续检测直到有人复活吧。 - 激活技能:说明已经移动到可以释放技能的程度了。 - 如果目标在攻击范围内,激活技能释放,buff进入==结束阶段== - buff结束阶段End:释放技能,然后关闭技能激活 - 移动攻击逻辑:如果在搜索距离内,如果==没有被UI主动修改了移动==,就发送朝向目标的位移操作消息。 - 结束移动攻击: 目标在搜索范围外,buff直接结束,发个位移为0的指令停止移动 -
一些常见BUFF¶
1. 正面/负面状态--【状态BUFF】¶
- 状态枚举:提供一个状态枚举存储
- 状态计数:在Attrs属性中设置相应的状态计数
- 状态改变回调:当任一状态发生改变时,设置状态事件(比如更新表现层UI显示)
- 属性检查计数:
- 有计数:一些状态需要将移动归零、禁止移动操作或者位移(比如击飞),用来模拟控制效果,继续启用该负面状态
- 计数为0:则取消对应状态,将位移回复。
虽然直接设置了位移,但是表现层还是会进行插值,看到的效果是缓慢击飞。
- 状态BUFF实现:开始和结束时增减某个状态计数就OK
2. 强化技能实现--【技能替换BUFF】¶
亚瑟宝剑大加强! 强化之后改数据、改逻辑?太麻烦! 直接做个新技能配置替换了!
- 新配置技能ID不变:还是和以前保持一致。这是为了避免其他逻辑获取BUFF时因为替换导致识别出错。
- 新字段:即替换ID,如果替换条件更复杂可能要加更多的ID
- originID:记录修改前的ID
- replaceID:记录修改后的ID
- BUFF逻辑实现
- 判断技能临时ID是否一致:
- 一致为0:代表初始没被替换的技能
- 不一致则修改临时ID:代表该技能已经是强化过的Skill了。
- 在技能逻辑类提供切换技能的函数:获取配置,修改技能属性。
- 计时结束End:自己将技能改回去
- 技能释放成功回调:注册函数,回调了是普通就触发end将技能改回去。
- 判断技能临时ID是否一致:
- 多重技能修改:比如后羿,分为被动普通,被动强化多重,一技能散射,被动强化一技能散射。情况太多,单技能通用不好处理。
- 判断当前SKill的临时ID,再确定替换的ID。
3. 目标标记效果--【标记BUFF】¶
本质上就是给目标的事件增添一个标记效果函数~
以标记加伤效果为例: - 标记效果:如收到buff的固定伤害(注意伤害绑定事件则需要取消再次回调OnHurt,避免循环回调)。 - Start时:buff目标将标记效果注册到事件(如OnHurt) - End时:取消标记效果在事件的注册。
4. 群体效果--【动态范围buff】¶
一般分为两种: - 以buff持有者owner为中心 - 以目标地点为中心
本质上也只是拿到实体列表动态搜索一遍加入到目标列表 - 效果实现:对目标列表逐一添加效果。
静态和动态范围:但是范围目标搜索也有差异,这里做个区分 - 静态范围:buff附着时搜索一遍目标。 - 动态范围:buff每个Tick重新搜索一遍目标。
5.立刻攻敌--【闪现移动BUFF】¶
有时候我们需要快速移动到目标前面进行攻击,这是就需要闪现来完成了。 - 瞬移距离:配置单独提供偏移量--buff开始的时候计算和目标距离,但是要做一点偏移,避免和敌方重合了。
6.☆效果叠加--【重置叠层BUFF】¶
一些效果可能会重复的叠加,并且随着层数增加逐渐提高强度。一段时间后层数可能全部消失或者逐渐消失。俗称:叠buff 这种buff效果一般需要两种参数 - 最大叠层上线:buff的叠加层数应该有限制 - buff重置时间:一段时间后buff层数减少。 实现: - 层数修改:BUFF本身缓存层数,条件成功后叠加,超时后减层或者层数全清。 - 清理效果:别光清理层数,效果记得清掉(可以用一个缓存来记录所有改变的效果,方便清理)。
7.技能释放影响--【成功回调BUFF】¶
有些buff是需要技能成功释放后才有效果。这种该如何修改呢? - 先拿到所有需要修改的技能 - 技能成功释放回调:给技能成功回调添加函数,执行需要修改的内容。
8.多重射击--【子弹BUFF】¶
个人感觉,技能系统提供配多个子弹的数组配置会不会更好?不过这里也相当于提供一个思路吧。像一些延迟、偏移······的特殊设置用通用逻辑挺麻烦的。
技能系统目前只有普通单个直线/跟踪目标射击,无法处理多个子弹的任务。所以使用buff来创建多余的子弹,单独设置偏移、方向、运动轨迹等。
9.实时变化参数--【动态参数BUFF】¶
对于会根据场景实时变化的参数,影响buff效果的BUFF,提供一了一个object数组用于传入参数,这样就可以做一些非固定参数的实现了。 - 当然,之前的成功回调buff某种程度上也算是动态取参了。只不过实现的时机有区别,一个用于创建,一个用于判定成功再修改。