[Unity2D]如何让角色的起跳与落下更舒适

Posted by RetenQ on 2021-10-30

[Unity2D]如何让角色的起跳与落下更舒适

本文概要

如何简单地通过四行代码,增加角色在“起跳-落下”过程中的操作体验
2D/3D通用,但是一般用于2D游戏中
涉及重力更改,不涉及跳跃代码

前言

在2D横版游戏中,跳跃常常是不可或缺的因素,甚至是主要因素。但很多Unity新手在设置跳跃力度与手感这一方面会遇到两个问题:
1.起跳困难,或者是跳跃力度过下
2.但是若加大了跳跃的力度,整体的手感就会飘起来

这一切的问题其实就是重力的设置,或者换句话说:很多2D游戏的跳跃,其重力尺度并非不变的

理论基础

我们以经典的Super Mario Bros 为例,如果我们逐帧分析过主角的跳跃轨迹,则会得到以下的轨迹:
示意图
(图源自Board To Bits Games,也是后文Better Jumping in Unity的作者)
注意前后的力度变化以及它们改变的节点,正是这种变化优化了“起跳-腾空-落地”的体验
它使得玩家操作起跳与移动的时间更长、距离更远,而最后作为收尾的落地却是十分干净利索的

代码实现

我们需要有两个重力尺度(也就是修改Physics2D.gravity)进行跳跃的优化,分别是起跳和落下的时候的值
分别设二者为lowJumpMulitiplier与fallMulitiplier,频道主Press Start的建议是二者的插值在0.5-1左右

实质上这是一个挺玄学的数值,毕竟这个东西是难以理论定义的,所以叫上你的数值hxd或者策划hxd自己去测测吧

两种尺度的切换点是跳起->下落的瞬间,因此我们依据Y轴的加速度rb.velocity.y判断即可

明白了理论之后,实现这个优化就简单得多了,正如Board To Bits Games所说,只需要四行

1
2
3
4
5
6
7
void BetterJump_Fix(){
if(rb.velocity.y < 0){
rb.velocity += Vector2.up * Physics2D.gravity.y * (fallMulitiplier - 1 ) * Time.deltaTime ;
}else if(rb.velocity.y > 0 && !Input.GetButton("Jump")){
rb.velocity += Vector2.up * Physics2D.gravity.y * (lowJumpMulitiplier - 1 ) * Time.deltaTime ;
}
}

其中fallMulitiplier是下落时修正的重力尺度,lowJumpMulitiplier是普通跳跃跃起的时候的重力尺度
这个跳跃优化可以单独作为一个脚本挂载,而不用对原本的跳跃代码进行修改,因为它是对重力设置进行了处理,而非对跳跃本身进行了改变

小结

优化跳跃中的“起跳-腾空-落地”体验,实质上是一个很简单的过程,但是它带来的gamePlay的提升却是很大的,正是这一点点的细节,不断加强这游戏的体验

Demo一周,扣细节一个月

此外,跳跃手感的优化还涉及到其它方面,如状态检测、按键延迟、短按长按区别等等,有机会的话我将在后续的文章中写出

参考

实战参考:A Perfect Jump in Unity - A Complete Guide
B站的翻译版:
【unity教程】如何在unity中实现完美2d跳跃【中文字幕】
理论知识参考:Better Jumping in Unity With Four Lines of Code