GameRes游资网

 找回密码
 立即注册

ACT技能编辑器的制作经验分享

发布者: D小游 | 发布时间: 2018-6-22 13:52| 评论数: 3

游戏程序
平台类型:  
程序设计:  
编程语言:  
引擎/SDK:  
文/Gordon

这是侑虎科技第407篇文章,感谢作者Gordon供稿。欢迎转发分享,未经作者授权请勿转载。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群465082844)

作者知乎:https://zhuanlan.zhihu.com/p/38001896

作者也是U Sparkle活动参与者,UWA欢迎更多开发朋友加入U Sparkle开发者计划,这个舞台有你更精彩!

技能编辑器功能演示(Unity版本为5.6.4p4)

缘起

我在一个新组建的团队里,只有一个策划兼制作人,加我一个客户端(公司美术内包)。我们需要在一个月内快速出一个ACT动作的Demo,Demo需要有至少三个角色和若干小兵,并通过评审会正式立项。当时我并没有做过这类ACT游戏,对这类游戏所知甚少,在策划的讲解,以及恶补了一些文章后,我们定下了计划:

1、在半个月内做一个技能编辑器,要支持编辑动作每一帧的攻击受击框,配置按键指令的招式转换,以及各种攻击数据的配置;

技能编辑器提高后续策划工作效率

2、同时制定美术制作动作的规范,以及我们如何切分动作,动作的复用和衔接;

3、第三周做Runtime的战斗逻辑,第四周整合资源,编辑器的配置,出Demo包。

计划

时间紧,任务重。我给自己的任务是不加班完成,并尽可能将编辑器功能提前完成,给后续留出更多的调整和DeBug的时间,因此需要:

1、尽可能和新策划搞清楚需求,做Prototype的推演,推演Editor下如何配置,Runtime如何执行。有经验的程序,会花更多的时间在前期的需求整理和逻辑推演上。

2、和美术梳理工作流程,让美术可以立刻开始做事情,后续能和我们的编辑器很好地对接。所以,在Demo阶段,美术只提供模型Fbx和动画Fbx,剩下由程序整合。

常用的动画分割方式

分析和选择

接下来,有几个技术点,需要做出选择:

1、是使用Animator 的状态机来做逻辑,还是自己做切换逻辑?


最终选择了自己做逻辑切换,核心就是工作流可定制。

Animator状态机自动生成,最简化,不包含任何逻辑和数据

2、是使用Unity的GUI来做编辑器,还是UGUI做?


最终选择用UGUI,主要是怕用GUI时间来不及。另一个原因是我希望策划能在一个技能编辑器下做所有的操作,流程一体化。不要那种在A Prefab上挂个脚本,再在B Prefab上挂个脚本,最后把A和B拖到C Prefab脚本的Field上这种编辑方式,这不利于策划理顺思路。(可对比白鹭引擎一堆Editor和Unity All In One)

3、如何做编辑器数据的序列化?


最终选择了自己做序列化,最主要的是数据和资源分离,以及热更新。

4、是使用Unity自带的Collider(物理系统)来做碰撞,还是自己做碰撞检测?


因为我们是横版游戏,所以,按传统的格斗游戏做法,只需要做Box,而且是不需要旋转的Box,自己实现的复杂度大大降低,那肯定自己做更可控。

简单总结下选择方案的思路:

  • 没有方案是对所有项目都合适的,选择适合自己项目类型以及开发周期,人员配置的方案;
  • 要着重考虑数据和资源的分离,热更新。考虑好和美术、策划的衔接工作流程,这些比逻辑本身更重要;
  • 可控性和开源,尽量使用自己熟悉和可控的实现方式,尽量选择开源的插件和工具。

关于ACT游戏,我的理解

我作为非ACT游戏玩家,我理解的ACT游戏和MMORPG,ARPG这类游戏的战斗表现上,区别如下:


所以,ARPG是介于ACT游戏和MMORPG之间,ARPG和ACT游戏,有着重大的区别(按策划的话:市面上太多所谓动作游戏,只能说是ARPG)。

ACT游戏需要具备:

  • 快速的操作反馈,需要玩家衔接好操作,才能输出最大化;
  • 招式衔接的丰富,不同招式下,不同时刻,不同按键,要切换到不同的招式;
  • 打击反馈的丰富,被击需要有动作反馈,轻中重,浮空等各种击中方式,被击者需要不同的动作反馈。

以上是一个非ACT玩家,做为程序开发者的理解,方便我区分当年做MMO的经验。

开动:以数据为基础来搭建框架

编辑器的目的是为了数据,所以,对于技能(这里只包含按键触发的主动技能)的数据组织如下:

角色数据图

ActorCfg:角色数据的根,包含所有角色相关数据;

ActorAttr:基础数据,包含资源Prefab ID,移动速度,重力,指令起始招式ID等;

指令

ActInfo:一个动作的信息,对应美术制作的一个动画(Animation);

动作列表

FrameInfo:每一帧的信息,一般包含攻击,被击框的信息(Position,Scale),以及一些复杂逻辑使用的标记;


动作游戏,需要给攻击和被击都打上框,没有被击框的帧,就不会被击中。

SkillInfo:招式信息。每个招式可以由一个或多个动作(ActInfo)组成,并可以选择动作的帧范围,这样最大程度地复用美术动作,并可以由策划自由发挥,组合出新的动画;

不同的ActInfo(Animation)组合出不同的招式

BoxInfo:不同类型的Box,不同信息。比如攻击,被击,霸体等不同Box的信息不同;

攻击类Box数据

HitInfo:攻击类Box,击中以后的数据配置;

当击中后,需要的数据,根据策划的需求来

ChangeCtrl:切换招式的数据。比如在帧范围(0~10内)触发了指令(Up),切换到招式xx;

Change To 招式 ID

SkillCtrl:各种技能处理,播放音效,特效,设置速度等等;

各种控制

Trigger:各种判断条件,条件达成,才会执行ChangeCtrl或SkillCtrl

各种Trigger

以上是主要的数据模块,ActInfo主要保存每一帧框的位置缩放信息,SkillInfo保存各种ChangeCtrl和SkillCtrl,并用Trigger来做为生效条件。后续按策划需求对技能编辑器的扩展,更多是SkillCtrl的添加和Trigger的添加。

通过这一套技能编辑处理,策划可以配置出丰富的表现效果。只要数据组织好了,同一数据,有不同的表现形式,这也是基础的MVC的适用。

对于习惯使用类似TimeLine编辑方式的,可以用Frameline方式(Gif压缩有点糊了)

序列化数据

编辑器,最重要的是数据的读写,也就是序列化和反序列化。

之前已经说明,我不使用Scriptobject和Prefab上挂MonoBehaviour来序列化数据的原因,不再赘述。现在放在手边的选择有两个,一种是序列化为文本(XML,JSON),一种是序列化为Bytes。

我最先是序列化为XML,因为我认为XML比JSON可读性强一些,刚开始我可以先手动写一个XML数据,Deserialize为对应的Class,等编辑器基本成型以后,再补上Serialize即可。

这样,我只需要设计一个根据Tag反射来自动化处理的方式即可(当时没仔细找,应该此方式有现成方案)。

通过Tag,可以写一套通用的序列化反序列化处理

XML序列化在前期的好处是,编辑器不稳定,数据经常错误报错,可以手动修改XML的数据,方便测试编辑器Bug,以及调试功能。XML还有很好的可读性,以及版本管理方便Merge。

但是当我们编辑器稳定后,XML的劣势就显现了:

1、序列化反序列化性能差;

2、这里需要给一些不支持String化的数据做支持(Color,Curve等);

3、序列化依赖变量Name,如果我们重构改了变量名(重构名字是常事),数据就丢失了。

经过调研,我们选择了用Protobuf来做序列化,直接解决了1和3的问题。需要了解Protobuf详情的请自行Google。

Protobuf来序列化,Protobuf的Tag

对于2里面的问题,需要做一些处理,将其Protobuf化

将Color Protobuf化

PBColor的使用

再结合AdvancedInspector插件(后面介绍)来使inspector下支持和原来一样的显示。


至此,基本上解决了序列化和反序列化的问题,最后我们将每一个角色数据,序列化,存为一个.Bytes文件。(带来的副作用,即不方便Merge,这里只有策划通过规范提交修改的流程,减少冲突,目前我们遇到很少)

一个角色对应一个文件,由编辑器读写

配合AdvancedInspector提供的UDictionary,我们可以方便地做Dictionary的序列化。

UDictionary

UDictionary的使用

到此,我们需要介绍一下,帮了大忙的插件Advanced Inspector(现在似乎有了更好的Odin):

https://assetstore.unity.com/pac ... ced-inspector-18025

具体使用我就不说了,大家可以去看他的Sample,对于在Inspector上做东西,方便很多很多。

SkillCtrl 和 Trigger的设计

在总体设计好之后,新加的技能方面的功能,主要集中在SkillCtrl 和 Trigger的添加。

这里在语义上是:当XXX的时候,执行YYY。 XXX就是Trigger,YYY就是SkillCtrl 。比如策划可以配置:

  • 当0~10帧时,播放技能特效;
  • 当10~20帧时,并且是击中状态,播放技能特效;
  • 当20~30帧时,震动屏幕;
  • 当20~30帧时,角色在浮空状态,添加人物残影;

在设计上,SkillCtrl和Trigger,都是这样:

1、定义一个TriggerType

Trigger Enum

2、定义Trigger的基类

Trigger Base

3、之后扩展,就是继承基类,加上配置数据,Override isTrigger方法,处理自己的条件逻辑。

Trigger Implement

SkillCtrl,主要包含一列Trigger,所有的Trigger都为True,就返回True。这里没有设计or的逻辑方式,Trigger之间,都是And的方式。


对应Runtime逻辑,一个SkillCtrl cfg,对应一个ctrler

Runtime Ctrler Base

扩展的时候,实现对应的Ctrler即可:

对应的播放声音 Ctrler

大部分游戏,需要设置逻辑主循环,在每一个Logic Tick,去检查Trigger,Trigger都为True,执行对应的Ctrler,即可。这里的Logic Tick,即对应编辑器里面的一个帧,同一概念。

接下来是一些小的点:

1、这里有一个小Trick,就是类命名用"_"分隔,前半部分一样,后半部分区分具体实现,可以通过反射来获得Instance类,以免做工厂,或者Switch case。

ActorSkillCtrlerCfg_Base cfg = U3DUtil.CreateClassByBaseType<ActorSkillCtrlerCfg_Base>(ctrlType);


2、在这样设计的过程中,遇到了一个问题,就是Unity的Inspector。声明是Base Class,但是赋值了Child Class,Unity的Inspector还是显示Base Class 的数据。

例如我希望在编辑器里点任何一个Ctrler,都显示对应Ctrler类型的数据。

资源的Ctler

对应的代码

Unity默认的Inspector,只会显示申明的类型ActorSkillCtrlerCfg_Base,而不会显示对应的特效数据。


这里解决方案很简单,引入Advanced Inspector即可,插件能自动显示真实Type的数据,这是Advanced Inspector帮助解决的最大的问题。

思考:每一个功能模块,我们要处理好完全不设计和过度设计的平衡,特别是一开始,不要过度设计。花时间理顺需求,尽量找准扩展点,把扩展点处理好,后续就是往上搭积木了。这个过程中,必然经历几次重构和优化,没有一次就做好的设计,重构是程序的核心技能。

编辑器和Excel表数据的配合

当我们开发Demo的时候,尽可能求快。角色的数据,我们就直接在编辑器里配了,比如攻防血,技能每一个Hit的伤害,招式的CD,消耗的SP等,也并未考虑招式升级了,基础伤害提升等,这些也不是编辑器应该关心的逻辑。

当项目正式化之后,我们需要解决的,就是数据,策划是配置在Excel里的,我们需要整合Excel数据和编辑器数据。

对我们来说,比较麻烦的是,我们结算伤害,并不是以一个技能为一个单位,而是以每一个Hit,一个技能,策划可能配置多个AtkBox,一个AtkBox,可能产生多次Hit,但是,我们不可能给每个Hit配置一个伤害,数值策划配置到这么细,他们会崩溃。所以,策划的Excel表,是以技能(招式)为单位,配置一个伤害。

数值配一个角色,某一个招式动作的总伤害数值

而技能编辑策划,在技能编辑器里,配置每一个Hit,对应这个伤害的百分比:


比如这个招式,策划配整体伤害1000,某个Hit这里配置0.4,最终结果就是1000*0.4 = 400。通过这种方式,将数值策划从编辑器中解脱出来,他们无需关心有几个Hit,只需要处理整体效果,技能编辑策划去将所有Hit的系数分割。当然,我们数值计算很复杂,这只是初步基础数值。

思考:这里其实是想说,将逻辑和数值分开来,各自关心各自的东西。这样,我们将Prefab(View),逻辑(技能逻辑),数值(Excel配表)都区分开来,按照一定的规则,在Runtime时候结合。

经验教训:

1、没有做整体的Undo和Redo功能,因为做Demo的时候,整体只有两周,实际大概一周半做完。没有时间设计整体的Undo,Redo。后续根据策划需求,解决了部分Copy,Paste,以及依靠Advanced Inspector的功能,做到了Inspector部分的Copy,Paste,也算基本不影响策划的使用。但仍然算是一个不足。

2、战斗整体预览,做得不够完整。目前在播放器里,可以在Play 招式的时候,对应播放特效,声音。但是不能所有SkillCtrl整体模拟。 之前想过在Editor里面跑一个简单的Runtime Battle,只包含当前编辑的角色和一个NPC,让编辑和预览能够无缝衔接。但是处理起来,有点麻烦。 现在的做法是在Runtime 的GM菜单中给一个接口,当打开技能编辑器编辑保存以后,将Runtime Cache的配置清空并重新打开战斗,选定的角色就会重新Load 新保存的配置。虽然这个方法不够完美,但也极大提高了策划的速度(以前编辑好一个,需要重新Run游戏,现在可以在游戏中实时更改,再进入战斗就更新),帮助策划提高工作效率,是程序责无旁贷的责任。

  • 有些部分设计得不够友好,策划配起来,有点麻烦。例如配置子弹的逻辑,目前做的不够好。
  • 我不想做一个大而全的,能通用的编辑器,我只想理顺思路,当我们下次做项目,或者类似东西的时候,能够在现有的基础上,通过裁剪和重构,快速得到一个符合项目需求的编辑器。(所以我的编辑器,不做任何Unity版本兼容)

现有编辑器,可以支持格斗,ACT,ARPG类游戏,如果做MMO和RPG,那就要裁剪到过于复杂的部分,简化即可。如果做点跑酷呢?那要这编辑器就没意义了,一切都要根据自己的项目来,不是越强大越好。

最后总结:

  • 当我们需要快速出Demo的时候,更应该理顺思路再动手,切忌上来就编码。把可能的难点先测试搞定,之后就顺手了;
  • 重构,不要怕重构,在合适的时间,做合适的重构,是我们程序的核心技能;
  • 组织好数据,让数据和美术资源分离,不要让美术资源的变化,干扰你处理数据的工作流;
  • 帮助策划提升效率,是程序能力的体现;
  • 做编辑器,要站在策划的角度,他们是用户,自己要用,才会发现问题,Eating our own dog food.

关于UWA:

由侑虎科技开发的游戏/VR应用性能优化平台,目前提供 1)性能诊断与优化 2)资源检测与分析 3)UWA GOT 三大工具,帮助开发者在短时间内大幅度提升性能表现;同时其搭建的知识分享的博客和答疑解惑的互动平台使广大开发者收益。


via:侑虎科技





GameRes游资网微信公众号二维码
关注我们官方微信公众号
游戏行APP二维码
下载我们官方APP-游戏行
游戏行APP二维码
关注手游动态微信公众号

最新评论

lingdan 发表于 7 天前
作为曾经用编辑器,后来在小团队限于程序水平,用xml的人,确实很怀念编辑器
justsolo 发表于 6 天前
整体的设计思路还是有一些缺陷,对战斗系统的理解不够透彻,因此编辑器就会稍显混乱

举个简单的例子, 战斗系统中,表层和里层要分开,【表】指的是纯粹的与战斗表现相关的,【里】指的是那些属性计算相关的(伤害多少,攻击产生多少怒气之类的),【里】的“值”务必单独拎到excel里,编辑器只负责跟主战斗系统相关的对象处理,否则会出现操作对象过多过杂的情况
想必你也研究过那个UFE (Universal Fighting Engine ),那就是一个非常杂乱的设计,把所有东西都塞到编辑器里的结果


另外,前期demo阶段不适合直接去做一个编辑器,因为需求可能在做的过程中才会慢慢明了,更重要的是划分好战斗系统的功能模块,尽量独立化


Cupids 发表于 6 天前
justsolo 发表于 2018-6-23 10:39
整体的设计思路还是有一些缺陷,对战斗系统的理解不够透彻,因此编辑器就会稍显混乱

举个简单的例子, 战 ...

比较赞同这个观点,尽管是编辑器,也应该奉行简单化,动作编辑就编辑,别将所有功能都扯进去,其实我觉得这样更加不利于开发,因为很多时候动作没问题,都是调整数据的问题,你让数值看着一堆没用的东西调数值吗?他们会更情愿看着excel… 跟写框架一样,每个功能还是尽可能单纯一些吧~
  • 手游还需要评测?!那我们来聊聊基本思路与
  • 《守夜人:长夜》 怀旧而惊艳的2D 横向卷轴
  • 从工业设计到游戏设计:形式、功能与游戏的
  • 《八方旅人》:味道正宗得不得了的传统JRPG
  • 灵魂筹码
  • 心动CEO黄一孟控诉百度上架“诈骗游戏”,

小黑屋|稿件投递|广告合作|关于本站|GameRes游资网 ( 闽ICP备05005107-1 )

GMT+8, 2018-6-29 22:00

快速回复 返回顶部 返回列表