金桔
金币
威望
贡献
回帖 0
精华
在线时间 小时
更新:现在看来,这篇文章其实有不少幼稚之处,当初也有很多东西没有考虑到,仅可部分参考。
最近对这部分内容研究得比较多,特此写成文章分享出来。
我们现在的技能系统可以分为三个部分
Editor: 使用基于行为时间轴的编辑器,得到Asset资产,用于进行技能表现的配置
Editor下技能表现的配置(资产、轨道、剪辑切片)
技能表现的预览(Editor+Runtime)
Config: 使用Excel表来进行技能数值的配置,它持有一个技能表现,这样做的目的是便于进行一个表现一致仅有数值不一致的技能配置,比如不同等级的技能。
Runtime: 一个技能实体的技能释放生效
首先是对于 Editor 部分,我们采用了 NBC.ActionEditor 的行为时间轴编辑器,它的好处是只定义了核心编辑器脚本,这也就意味着一切业务相关的东西都将我们自己来编写,可定制化非常高。
对于技能编辑器主要可以分为两个部分,一个是轨道(Track),一个是剪辑片段(Clip)
一个轨道上会包含一系列剪辑片段(Clip),我们可以增加自定义的轨道,也可以给该轨道增加一个自定义的剪辑片段,而剪辑片段就是我们技能表现的核心,比如播放一个动画,播放一个音频,播放一个粒子特效,屏幕震动,这些细化下来的表现事件都是编写剪辑片段来实现。
但是现在的技能编辑器其实还有一定的局限性
1. 技能编辑器不支持条件和分叉,这其实也是为什么另一种主流的技能编辑方式是通过行为树来实现的,比如要该技能要在击中敌人时才播放一个粒子特效,现在的解决方案是把这个判断的逻辑写在 clip 里,比如在粒子特效clip里加一个参数进行控制,具体根据业务来实现。
2. 一些和自己业务系统的连接,比如想要实现一个移动到某处的clip,调用自己的运动系统的话,因为使用到了 Animator 等非Editor下的东西,所以会导致无法预览,不过这和具体的业务有关,和编辑器无关就是了。
我们要将数值和表现进行解耦,技能表现就是通过之前的剪辑片段组合实现,而技能的具体数值则是通过Excel来进行静态数据配置。初步设计后设置参数
除去配置必备的三件套(id、name、desc) 之外的核心内容就如下几个部分
技能效果列表: 如造成多少伤害,增加多少防御,造成持续伤害等等,而配置表里则通过自定义一个格式进行配置,第一个参数是 function name,这个 function 写在技能的实例里(为什么不写在生成的技能静态配置类里是因为会使用到一些运行时数据),后面跟的是这个函数的参数。代码里对这个字符串进行解析,然后去调用对应的方法。
技能表现: 就是对应通过编辑器制作的技能表现
技能图标
技能消耗
其实可以发现,这里面最主要的数值配置就是技能效果的配置。
接下来是对这二者的一个整合,一个技能实例,在 Runtime 下是如何生效的。
我们将一个执行的任务进行抽象,一个 TaskStatus 有如下几种状态
任务未执行(None)
任务执行中(Running)
任务执行成功(Success)
任务执行失败(Fail)
一个技能的实例应该包含技能配置(SkillConfig)和技能的释放单位(BaseUnit),因为一个技能表现存在多轨道,所以我们对于多轨道,应该是有多个 TaskRunner 并行运行,对于单个的轨道,则是按时间顺序执行。然后再在技能实例里实现各种技能效果即可,根据业务进行。
其实写到这里,整个技能系统的架构,包括需求,其实已经清晰明了了。写在最后的是,关于技能编辑器,现在主流的方案有两种,其一是基于行为树,一种是基于 Timeline,二者各有利弊,但是,我们为什么不能将这二者进行结合呢?事实上,它的本质没有改变,依旧是使用变量对接下来要播放的clip进行判断,唯一的区别是,我们之前的做法是将这部分逻辑写在代码里的,而和行为树结合的话,就可以把这部分逻辑给抽离出来,进行可视化的配置,效果会好很多。
原文地址:https://zhuanlan.zhihu.com/p/722139028
楼主热帖