查看原文
其他

游戏角色动作系统如何设计?这些经验值得学习

lingzerg 腾讯GWB游戏无界 2022-08-30

编者按 为什么说3C是游戏的基础?在设计游戏角色战斗时,需要注意哪些细节?本文作者lingzerg分享了自己开发角色动作系统的一些经验。


本文内容由知乎专栏“番茄的游戏开发世界”提供,转载请征得同意。


3C(camera,control,character)作为任何游戏的基础,为了以后还有机会做动作类的游戏,也是对之前经验的总结,我把所有的信息整合在这篇文章里,方便以后查阅,也分享给大家,希望得到更多的指点。


关于3C


关于3C我认为最重要的一件事是有爱,那么根据重要程度排序是这样的:1、爱;2、细节;3、架构。


爱决定了细节的数量和高度,细节决定了质量,架构决定你能不能开发一个能用的东西出来。


我想说其实大部分问题都是看你有没有业务感知能力,感知到一些细节还有问题,这一块基本上靠策划是不靠谱的,策划毕竟不能实现,所以gameplay是一个极其吃经验和爱的职位。如果你不是一个深爱你做的这个类型的game play 仅靠工程能力, 这个手感一定达不到顶级。


并且, 3C的camera是另外一个大坑,我用的Cinemachine,但是负责任的说,如果要追求好的3C相机必须自己做,但是control和 character应该在一起做,我只做了后者也是对工程量的妥协,整个系统我从18年8月开始做,期间得到很多大佬的指点和帮助。


动作系统实际上就是一个ACT的核心,当然你拿他做RPG也没问题。大致分为美式和日式,日式更多的是走的打击感、操作性;美式走的一般是真实感,而真实感需要大量的资源和黑科技加成,例如 motion matching。所以我的整个基础是基于日式的风格做的。


我认为整个日式动作游戏的3C水平,大致可以这么划分: 《塞尔达》-《黑魂》 -《只狼》- 《鬼泣》or《猎天使魔女》,当然这么分很不严谨,这是我的认知。


整体的导图如下:


(原图下载链接:https://share.weiyun.com/5AcnUja)


如果你对战斗系统很熟悉,可以直接跳过文章直接看思维导图,会更方便和直观,更多的描述用于新接触战斗的萌新方便上手。


我们分为几个大类描述:


1. 可配置性 - 可配置性决定了这东西做出来是否能用,如何配置一个怪物,配置一个角色,配置一个boss。

2. 动力学和动画模块分开 - 这样处理能避免大部分的奇怪问题,并且在结构上更为方便维护。

3. 状态管理 - 状态管理对玩家的输入如何处理,前摇中段后摇如何处理,这里我开始漏掉了,我朋友告诉我应该谢谢状态管理,所以文章完成后扭头来写这个的时候其实我已经没劲了,最后写的实在是写的很崩溃,因为内容太多,每个地方都要想半天当时怎么做的,什么思路,还要对照代码,如果这里有不明确的地方希望有兴趣的童靴给我留言,这里我补充一点,unity的状态机不是很好用,如果有工程能力的同学,建议自己手动管理,仅仅用animation controller的混合树就好了,我就是这么做的。

4. 动作的细节处理 - 这是一些经验之谈。

5. IK的简单描述 - 其实IK的应用就那么几个点,具体的功能点就自己摸索摸索吧。

6. 物理和动画的互相作用 - 这里是进一步提升的方式,但是我并没有做物理相关的东西。

7. 黑科技 - 如果你想把3C往更深了做,这些方向可以考虑。


可配置性


角色模板


可配置性是一个框架是否可用的标准。


所以我们放在第一个讨论,这里关系到你的工程能力,一般第一次做重构个3-4次太正常了。所以大家放心大胆的开发,后面多重构就好了,不用考虑一次性开发一个完美的系统。


如何考虑可配置性呢?我们需要从业务出发,抽象出我们需要的类型。


  • 角色 - 怪物和玩家都属于角色的一种。

  • 角色需要动作 - 动作让角色动起来,每个不同类型的角色可能需要不同的动画,但是角色之间有没有共性?

  • 如何播放?事件和角色的关系,这里还要考虑AI,其他玩家操作输入,网络等。


让我们进一步抽象。


有没有可能有几种角色,长相差距很大,但是动作是类似的?例如拿刀的骷髅兵和拿剑的人类士兵,同时需要攻击动作、idle和走跑。可能骷髅兵的攻击只有两下,人类士兵会多一个跳劈。并且我们支持非空判断,如果特殊攻击时空,就无法触发。


那么从动作组上我们这样分类这三个单位:骷髅兵 - 弓箭兵 - 人类士兵


  • 角色A - 关联动作(攻击, idle - 移动 - 特殊攻击)
  • 角色B - 关联动作(远程攻击 , 移动)


在此之外,还要考虑什么事件可以触发,例如攻击就是攻击事件触发,可能特殊攻击需要一个 扳机状态 + 攻击触发,那么基本上大思路就出来了。


我们需要一个模板A 角色模板,支持配置模型 动作组,以及一些参数。还有每个动作相关联的事件,这样的东西有较高的配置性。


我做了如下模板:



当然,你可以根据你的业务需求调整。


下面的bing action setting 是用来绑定对应事件的。


红色的代表该bing action 有问题。


左边是状态,右边是对应事件,none代表没有状态。



这样,我们的角色模板就创建好了。


动画组


然而关联对应的动画组,我们也需要考虑角色的动画有那些类型。


例如最简单的 idle - 走 - 跑 - 攻击 - 特殊攻击 这些动画背后有关联着那些内容呢?


idle - 走 - 跑,这三个被称为locomotion 是一个角色的基础动作组。


我这里采用的是一个动画组支持多个locomotion,放置一个角色有多重基础动作。


例如一个角色有锤子, 和 举起锤子两个状态 , 举起锤子的时候可以移动, 那么locomotion里的移动动作必须全部换新的, 并且这个角色还可以切换武器 - 太刀, 那么所有的动画片又被替换了。


所以最后动画组是这样的:



上面是一个基础的locomotion,下面是对应的其他locomotion,再往下是具体的动画业务,这里最好的状态是下面的动画根据上面locomotion的切换也有一定的可编辑性,但是我当时并没有做。


动画片的意思是例如攻击、[idle - 走 - 跑]、翻滚 , 这些动画的类型如何处理。


我们当然可以直接播放动画片,但是一个动画片包含了很多可能性,这些可能性我们应该做成可配置性的。


locomotion 的做法我采用了是否的选择,例如考虑到巨型怪物可能只有走,或者某些小型怪物只有跑,走和跑还有idle都是用于的可选项。


locomotion动画片的选项如下:



你可以考虑是否有疾跑、跑和走。


很关键一点在于生成locomotion以及对应的混合树,我把最复杂的混合树截图出来,其他的大家自己研究吧,有问题可以留言。


这里的关键点在于走和跑的分离,这样在左右横移的时候,不会出现这样的状态切换 [左横跑 - 左横走- idle - 右横走 - 右横跑],双层混合树的好处在于直接变成:[左横跑 - 右横跑]。



当然,直接八向混合也可以,但是如果追求细节不要这么做。



最基础形态就是全部取消,只有idle:



因为动画状态特别多,如下:


public enum AnimationType{ None, //基础状态 Locomotion, //基础运动状态 Animation, //普通动画 Combo, // 攻击,连击 MaskAnimation, // 遮罩动画 LoopAnimation, //循环动画 BeAttackedSimple, //单向简单被击 BeAttackedFourDir,//4向被击 BeAttackedFourDirTwoAnim // 4向被击, 每个方向又支持两个不同被击(伴随攻击方向切换)}


我再用一个典型的举例,就不多讲了。


如果讨论动画组,不讨论combo也太不厚道了。



combo我大致是这么做的,可以支持多个动画片,在播放时根据长度连续播放这样就支持连击了,而且可以选择遮罩,例如只有上半身,只有下半身,每个动画片绑定自己的前摇和后摇。还有是否支持root motion等。


再举个例子就是被击:



被击可以选择有效图层和具体播放动画片的朝向,这个根据你的业务具体安排。其他例如loop动画,普通animation,就是可以配置前摇后摇时间即可,loop要支持三个动画的循环,在动画播放结构中也需要支持。


动力学和动画模块分离


这里的核心思想是:PlayController需要将输入交给动力学组件,同时将动力学组件的内容,交给Animation组件。需要根据真实移动速度来决定动画状态,而不是输入向量,基于这个大的思想,可以保证一些奇怪的问题不要出现。而动力学的核心在于处理特殊情况。


这里的类结构大概是这样:



Kinematic大概有几个大的业务要考虑清楚:


  • 撞墙 - 撞墙的处理关键在于不要穿的太厉害,当动力学组件遇见墙体时候,Rootmotion依旧会执行,这时需要同步角色位置到当前动力学组件的位置,这个是基础。
  • 边缘检测 - 边缘检测在于下滑,一般人物会用一个胶囊体,这个胶囊体会卡在边缘,这里要处理的平滑,下落既是下落,而不下落时人物要站扎实不要抖。
  • 跳跃1 - 原地起跳 - 原地起跳最好用一个独立动画,问题的关键是当前跳的落点是高低不平还是平面,因为资源和时间的问题,我直接用跳跃处理的这里,当动画播完还没落地,我就认为地面是不平的直接过渡到跳跃循环。
  • 跳跃2 - 冲刺起跳 - 当玩家加速跑时,这个起跳必须和普通跳跃不同,否则没有那种速度感,同时向前跃起,这里最大的坑在于可能你刚起跳就撞到物体了,好一点的或者美式动作游戏会处理一下,给个撞击动画,但是有些游戏也不处理,尤其是日式游戏,硬播完对玩家来说并不是不可接受的事情,冲刺起跳后落地最好也接一个落地动画,例如翻个跟头,而撞墙就不适合播放,这里具体如何处理就要看GamePlay的爱了...
  • 跳跃3 - 向前跳跌入悬崖或者落地 - 跳跃其实分为是哪个部分,起跳、loop、跳跃落地,落地又分为下落时间过长的大硬直和下落距离不大的小硬直。
  • 爬梯子1 - 分为三个状态,上梯子、下梯子和爬,这里最好给一个固定动画,由程序控制正播或者倒播,比较麻烦是对上点,并且要动力学组件配合,这里还有个做法就是用ik让手和脚找梯子的挂点具体就看GP的爱吧...
  • 爬梯子2 - 还有一个坑就是爬梯子的时候,被击怎么处理,《黑魂》里是给人物一个抖动,死了就直接跌落。
  • 爬峭壁 - 这算是比较恶心的一个点了,爬峭壁的核心在于配合IK以及关卡设计,以及庞大的动画状态,这个状态属于一个全新的locomotion,我当时只是试了一下挂在峭壁上,然后按跳跃就播放跳跃,然后扒到下一个挂点。


其他的就不写了,有问题请评论追加...


状态管理


首先unity的animation controller提供的混合树非常好,但是状态却有一些不疼不痒的bug,例如A状态到B状态的过程中,切换C状态这时会出现闪一下切过去,上下半身的动作会又互相影响,修正起来比较麻烦, 所以我干脆就自己管理状态,让unity直接执行就好了,手动管理状态,把ac内部的混合树当一个状态调用。


而和状态在一起的,还有一个关联项目就是对输入的处理。


输入可能有三个来源:


1)玩家手柄或者键盘


2)AI行为树


3)网络


不管哪个来源,我们可以用同样的抽象层让输入统一。


输入分为几个类型:


1)普通事件 - 不要让玩家的输入直接操作动作,一定要做一个转换,尤其是移动,移动的朝向交给动力学,动力学作用于动画系统,而按键输入一定要转化为一个类似行为的抽象。


2)状态转换型输入 - 某些按键实际上是一个状态,例如,玩家按下收刀实际上角色要进入到一个收刀的状态,此时攻击键变成了一个特殊攻击,相对应这个状态下的输入都出现了变化,所以一个行为应该是基于状态的,关于这个状态和事件的区别大致是这样的:


这个状态手柄上一般会用扳机键


3)输入的时效 - 一般一个动作分为三个阶段 - 前摇、执行中、后摇,你可以指定三个阶段那个是有效输入阶段,例如我一般会屏蔽前摇的输入,执行中是有效输入阶段,后摇就处理玩家输入。


4)输入指令的重排序 - 这里很重要的是当一个动作执行中,玩家的输入要如何处理,后摇就开始执行之前输入的动作进入预混合阶段,而且后摇这个时间点我推荐对动作进行排序,例如当前是攻击,那么要做一个输入的优先级排序,优先级最高的可能是下一个攻击,而翻滚之后,优先级最高的可能是喝血,不要根据玩家的最后一次按键去执行,这里对感受的提升是巨大的。


动作的细节处理


攻击和翻滚相关


*攻击、翻滚的前摇最好不要锁方向,这样玩家容易攻击之后怪物因为移动躲开了,最好的量我感觉最好根据不同动作,每个单独设置。


* 攻击 - 攻击的核心在于Root Motion,但是细节又有好多讲究,例如如何定帧,是真的停顿还是减速,攻击的碰撞又有几种方式,有直接绑定碰撞盒的,有攻击最后一个伤害帧算扇形面积的,攻击中还可能有被击,被击怎么处理。


*攻击还有一个特性就是3D场景下的攻击,容易让玩家产生错误空间感受,所以要增强玩家在3D场景下的攻击范围,或者敌人伤害的触发范围,这个要结合是否有PVP单独调整。


*翻滚 - 翻滚我因为动作资源的限制用一个翻滚,然后角色转向的方式处理,其实最好的方式应该是8个方向分别用独立的动作,翻滚很重要一点是启动的时候,需要给一个旋转的时间,也就是前摇不要锁方向这一点是通用的。


locomotion相关


*locomotion其实决定了一个手感的基础,大部分的动作都是由locomotion过渡的,这里双层混合树是指第一个混合树用来做当前速度,朝向的判断,第二层有三个对应的混合树。


idle,当没有速度的时候,就默认idle。


走,当速度不够跑的时候,就默认用走。


跑,速度够的时候就切换到跑,之所以要把跑单独出来,是因为有一个特殊情况,就是玩家在向左平移时,突然向右,有一个瞬间会速度到0,例如从左到右,速度会这样变化: [1, 0,-1],此时如果走和跑用一个混合树,动作会过渡到走,然后过渡到跑,这里会有一个微小的卡顿,很不舒服。


直接根据速度和方向切换到走跑,这样在一个平移中,例如向左横移,突然向右,会有一个微小的过渡卡顿,跑-走-跑,而实际上这是不符合人的移动习惯的,但是在一个情况下例如怪物没有走路的动画只有idle和跑,或者没有跑步,只有idle和走,那么可以用单层混合树搞定全部。


特殊动作处理


在某个武器的状态中,要支持一个或者多个特殊状态,例如太刀的收刀,大锤子的蓄力,有些特殊动作会禁止移动,有些特殊动作释放中可以移动,那这里我感觉最好是切换locomotion。


切换武器实际上相对应的很多动画都要切换,我这里用的是直接切换全套动画组来处理,例如双刀切换到单手中剑,这连idle都切换了。


被击


被击实际上是打击感的核心,一个动作的受力做的极其好,但是没有攻击物体时,你是感受不到力量的,但是一个动作做的一般,但是被击做的非常到位,此时你可以感受到攻击后的力量,这个力量感就是被击表现,被击的核心有几块: 停顿配合,击退距离和攻击移动距离要配合,连续攻击后击飞,音效,特效等等。


被击方式1 : 攻击原地不动,被击者微小后退,几下后击飞或者退出攻击距离(《塞尔达》),这是一种对怪物的保护,连击几下后怪物就被击飞。


被击方式2 : 攻击者前移,被击者后退(《黑魂》)。


被击方式3 4向被击 - 四向被击对被击的体验提示是很大的,而且被击本身最好支持Rootmotion,攻击对象被击后后退对被击对象也是一种保护,拉开与攻击者的距离,还要配合击倒,并且可以支持4向-同时支持每个方向根据攻击角度不同采用2种不同被击。


击倒 - 这其实是一个保护性动作,击倒后角色不可以被二次攻击,当然也有可以被攻击的《鬼泣》里的就有这里就看具体策略了。


硬直中的被击处理


硬直被打断 - 直接转入被击,这里的处理没有特别好的办法,被击的关键在于快速反馈,直接决定手感是否刀刀入肉,所以如果连续被攻击,就会出现抖动,如果例如被4个人前后间隔不到一秒攻击4下,这里可能要特殊处理。是否要从第一个被击直接过渡到第四个,中间2个干掉一个,甚至直接干掉2个。


硬直没有被打断 - 硬直动画例如蓄力攻击中被攻击有可能不会破坏硬直效果,那此时最好混合一部分被击,让人物有一定抖动,否则也会很假。


处决


处决的核心在于把两个角色的相对位置弄的差不多,比较糙你就直接滑过去,然后两个动画的同步播放,例如《黑魂》的背刺,你到达指定位置可以触发了,咱们就直接滑动调整位置,一般处决玩家就无敌了,《只狼》也是这么做的。


另外一种就是类似QTE的,这一种又分好几种,例如莎木的就比较弱鸡,但是战神的就比较猛,这个我没做过。


Gameplay 到过场动画的无缝衔接


摄像机平滑过渡的切换和角色动作的切换,这个没做过,难点在于摄像机和角色如何抵达预定位置,中间还是平滑的,看看战神...即便不做成战神那样,这个细节量也很大。


关于IK


我是用的final IK 解决我的ik问题,所以这里我不展开讲了,主要处理这几个问题:


  • 楼梯上脚悬空的处理
  • 开门是用ik还是固定动画
  • 拿桌上、抽屉内物体
  • 死亡后的纸娃娃效果
  • 头部朝向锁定目标或者场景内重要物品


物理和动画的相互作用


物理这里完全没做过,不过听某些大佬讲,这里处理好可以增加真实感,例如攻击的时候被击,被击没有打断攻击状态可以加一个10-30%的物理状态的抖动到攻击身上。


例如你被前面的敌人攻击然后背后也有人攻击你,此时如果不处理就是抖动到背后的被击了,因为被击必须快速切换,响应慢了就假了,被击直接影响手感,听某些大佬说可以考虑混一点物理,这样抖动的效果会更好,但是我并没有试过。


这些黑科技


motion matching是育碧搞的一个动作匹配技术,基于目标的位置和方向速度通过算法从数据库中取用匹配动画,需要大量的动画片支持,同时还要预判断未来地形变化,总之很黑科技,没有足够的动画资源基本没办法做,美式动作游戏或者冒险游戏里大量的使用该技术。


例如当一个角色的动画是变速的时候,如何保持动作的受力感受同时又可以变速,例如某个技能可以根据玩家输入加快速度,或者减慢速度,某些游戏会考虑尝试多套动作,但是高级动作游戏例如《鬼泣》,显然不是这么做的,至少我感觉不是这么做,也可能是我感觉错了。


动作中断后如何和下一个动作保持良好的衔接-好吧,讲的直接点,我实在不知道《鬼泣》和《猎天使魔女》怎么那么灵活还那么流畅的,不管我怎么处理混合总感觉混合时间不够,或者动作幅度特别大就变的很奇怪,这里我感觉暴力一点就是做大量的中间动作片加强过渡,不过只能是猜测了。


其他


还有一个很重要的点,就是游戏策略 -实际上在制作动作系统的时候要考虑兼容各种策略,但是在调手感前,要先想清楚自己的战斗策略,所谓战斗策略是指博弈方式,以及对玩家的操作进行约束,约束具体是指你需要的是一个黏糊糊的手感,还是一个干净利索的手感,而整个战斗博弈是什么样的,如何保持有效博弈的同时,让玩家特别明确,例如剪刀石头布的方式?或者是打地鼠?亦或者是节奏游戏?或者搓招?


关于战斗反馈 - 这一点是关于给玩家的信息的,所有给玩家的信息绝对不能是单一的,例如被击,被击相关联的信息,我之前看过一篇文章他们做了11种不同的反馈方向,保证玩家至少能接收到3-4种,例如声音、攻击特效、手柄震动、屏幕效果、动作反馈、环境反馈等等。这种信息量越多,玩家就越明确,这里还涉及到上一条战略策略,玩家游戏失败的原因归错到游戏的可能性也会更低。


希望有一天我也能开发出像《黑魂》、《只狼》这样游戏设计和技术完美结合的游戏。




您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存