(翻译)游戏双摇杆:辅助瞄准: Everything I Learned About Dual-Stick Shooter Controls

原文:

https://www.gamedeveloper.com/design/everything-i-learned-about-dual-stick-shooter-controls#close-modal

 

Everything I Learned About Dual-Stick Shooter Controls

Dual-stick shooter controls on a gamepad should be a completely solved problem by now, shouldn’t they? When I started developing my open-source game Relic Hunters Zero on my spare time last year, I was very surprised to realise that I’d have to bang my head against multiple walls to get everything up to an acceptable level of quality. Granted, there are a few good bits of information here and there on the internet, but it’s all very scattered and hardly enough for a first-timer on the genre like me.

双摇杆射击现在有成熟的解决方案

Now that the game is nearing its release I decided I might as well aggregate, in a single article, all knowledge I gained on the subject through research, trial and error, and mostly by obsessing over the tiny details that make all the difference.

这篇文章是我调研后的总结。

Zero is the major example I’ll use below, but you’ll find that it’s a good one - it contains pretty much all of the tropes and control scheme challenges in the genre. So strap your belts, grease your control sticks and let’s get on with it, shall we?

我的游戏Zero是很好的例子。

 

Understanding Axes and Implementing Deadzones Correctly

理解Axes并正确实现Deadzones

Analog stick input is composed by two axes (usually “x” axis and “y” axis) with values that range from -1 to 1. “0” is the absolute center, while “1” or “-1” represent the very edges of the stick, either up/down or left/right. By combining these two axes we get 360-degree directional input with an “intensity” value that ranges from 0 to 1.

摇杆输入由x、y轴组成,每个轴的值在[-1,1]之间。0是每个Axes的中心。在二维平面上我们可以获取360度的朝向。

So what is a “deadzone”, you ask? When you are not touching the stick, even the best possible gamepad won’t give you a perfect “0” value for any of the two axes. What you normally get is a frenetic value switch, usually on the 0.05 to 0.15 scale on quality hardware. So if you just use that raw input in your game - say, for movement - you will see your character twitching in all directions like a pudding having a seizure.

即使手柄硬件再好,当你不操作摇杆时,获取的值也不是精确的(0,0),

通常在 0.05到0.15之间。直接用纯粹的数据控制player移动可能会导致没有输入的时候player在抽搐。

(使用unity有个dead值的配置去控制此问题 )

https://docs.unity3d.com/Manual/class-InputManager.html

 

That’s when the deadzone comes in. We ignore all values below a certain threshold, smoothing out the rough patches of the input. The idea itself is pretty simple, but you would be surprised at how often it is implemented the wrong way! Actually, on both the engines I normally use (Game Maker: Studio and Unity) I find deadzones to be handled poorly, so I tend to get raw XInput data and code the deadzones myself. 

比较简单的做法是超过deadzone定义的阈值后再响应输入。不过作者发现unity处理的并不太好。准备自己实现

On my first implementation I made the rookie mistake of just checking each individual deadzone to see if either one is above my desired threshold. For example, if it’s a 0.3 deadzone, my code would be something like this:

if ( Math.abs(joy_get_axisX()) > 0.3 ) || ( Math.abs(joy_get_axisY()) > 0.3 )
{
    DoTheStuff();
}

 第一版实现作者犯了个新手错误,直接判断阈值。

下面的实现更不对:

if ( Math.abs(joy_get_axisX()) > 0.3 )
{
    DoTheXStuff();
}

if ( Math.abs(joy_get_axisY()) > 0.3 )
{
    DoTheYStuff();

Sutphin’s article goes on to offer an even more sophisticated model, which he calls “Scaled Gradient Deadzone”, based on the idea of smoothly “killing” the input instead of instantly dropping off to 0 when the deadzone is reached. While it is an amazing tool for a FPS game, I found it to be overkill for Relic Hunters Zero, so after a few tests I ended up sticking with the simple radial deadzone. In fact, let’s talk more about what I’ve learned, and the differences between FPS and dual-stick shooter controls.

Sutphin的文章继续提供了一个更复杂的模型,他称之为缩放梯度deadZone,基于平滑地Kill输入,而不是在magitue到达deadZone时立即降为0的想法。不过作者测试后,发现直接用magitue对自己游戏体验更好。

我找到了一个实现:

https://gist.github.com/DataGreed/c7c7c15d2cf009bc63966e60f44be522

分析InputWithRadialDeadZone和InputWithScaledRadialDeadZone区别:

 

 

 

Analog vs. Digital Input

A constant lesson for me was that concepts that are perfectly fine for digital input don’t always translate well for analog. As a huge fan of FPS games, I came into Relic Hunters eager to try a lot of neat control tricks that make these games feel great, usually to no avail

So let’s begin by understanding how FPS aiming is different from dual-stick shooter aiming. In first-person-shooters, input is digital - there is no direct correlation between the position of the sticks (intensity and direction) and the position of the crosshair (a pair of coordinates on a cartesian plane). Dual-stick Shooters are analog - the firing direction correlates with the direction of the stick.

双摇杆射击方向和摇杆方向是相关的。

固定视角的FPS游戏(射击十字在屏幕中心),摇杆的方向、强度和准心的位置不是直接关联的。

Analog/Digital vs. Analog/Analog comparison

This changes everything. First of all, as I’ll demonstrate below, assisted aiming becomes a real challenge. Also, the player is always holding the input down! While in FPS games you can “rest” your right stick after you place the crosshair where you want it, in dual-stick shooters you have to keep holding it.

双摇杆游戏你必须一直握着Stick,FPS游戏中设定好方向后就可以放下摇杆了。

This means that you can never expect players to use the right-stick and the face buttons (XYAB on Xbox, Square/X/Triangle/Circle on Playstation) at the same time. Any actions that need to be executed while you aim must be mapped to the triggers and shoulder buttons, so we have to design accordingly. Of course, mapping is a matter of preference (you should always offer your players the option to remap their controls), but you have to make sure that you don’t have more than 3 or 4 commands (ideally 2) in your design that must be executed while aiming.

这意味着你永远不能期望玩家同时使用右摇杆和正面按钮(Xbox上的XYAB, Playstation上的方形/X/三角形/圆形)。

当你瞄准目标时,任何需要执行的动作都必须映射到Botton和Top按钮上,所以我们必须相应地进行设计,当然,映射是一个偏好问题(你应该总是为玩家提供重新映射控制的选择),但你必须确保你的设计中不包含超过3或4个命令(理想情况下是2个),这些命令必须在瞄准时执行

A great rule of thumb (no pun intended) that makes up most of the good feel of Relic Hunters’ controls is that the aim must never, EVER snap into position. If you translate stick input directly into in-game look direction you will get very jaggy results that look and feel awful.

如果你将Aim摇杆输入直接转换为Player Look方向,你将得到非常粗糙的结果,看起来和感觉都很糟糕

So, my first commandment: directional input should always be interpolated. Even very high-speed rotation (say 12 degrees per frame in a 60fps game) feels much better than snapping towards the input position

方向输入总应该被插值,即使帧率非常高。(作者下文又推翻了这个准则)

摇杆输入和player朝向的插值,如下图: 

Gap between input direction and in-game direction

The way I do it is to have two different directions: a “target” direction that comes straight from input, and a “view” direction that is displayed in-game, and rotates towards the target direction with a set speed. I also recommend having a “minimum difference” between the two values before moving, which will compensate for the tiny variations on axis value that you may get from hardware.

同时建议两个方向超过最小minimum difference后才进行插值,用于补偿硬件的轻微抖动(轻微的角度差不进行插值)

The speed with which we rotate this “view” direction is the “aim sensitivity”. Higher sensitivity will give you snappy, agile input with smaller precision, while lower sensitivity will rotate slowly providing you with increased accuracy at the expense of responsiveness.

Aim 灵敏度:我们把player旋转朝向的速度定义为Aim灵敏度,高灵敏度会较小的精度提供快速输入,低灵敏度会让player旋转比较慢,不过玩家的精确度会高一些。

One neat trick that I soon learned is that you don’t have to choose - at least not all the time. Just as FPS games change aiming sensitivity depending on the situation, so can dual-stick shooters! In relic hunters I use a high sensitivity when you just move the right stick to aim, but a much lower one when you hold Left Trigger to enter the special “laser sight aiming” mode. I also zoom in and move the camera a little bit towards the aiming direction to better communicate and smooth out the transition.

作者的策略是:只移动RightJoyStick进行瞄准的时候,提高灵敏度,但是当玩家按LT开启Laser激光瞄准的时候,作者使用了低灵敏度,并且拉近一点点Carmera. (作者的这个游戏是 右摇杆没有激光瞄准线,LT会开启激光瞄准线)

Two different aiming modes in Relic Hunters Zero

But that’s not all you can do. There’s a very cool aim assist tool in console first-person shooters called “Sticky Aim”. The idea is to give you an invisible helping hand by detecting that your crosshair is on top of an enemy and then dramatically decreasing aiming sensitivity - this way you can acquire targets and keep them in your crosshair much more easily. You can see this trick while aiming in gamepad-focused shooters such as Halo 3 and Borderlands 2, and it is even used in Destiny’s mouse-like interface to help you click on the butto

还有一种(Sticky Aim)的辅助方式 

"Sticky Aim"(粘性瞄准)和"Auto Aim"(自动瞄准)是射击游戏中两种辅助瞄准功能,它们都旨在帮助玩家更容易地锁定目标,但它们的工作方式有所不同:

  1. Sticky Aim(粘性瞄准):

    • 粘性瞄准是一种当玩家的瞄准准星接近敌人时,游戏会稍微减慢准星移动速度的机制。这种减速效果使得准星在敌人附近"粘住",从而帮助玩家进行微调以准确瞄准。
    • 这种机制通常比较微妙不会直接将准星吸附到目标上,而是为玩家提供了在接近目标时更精确瞄准的可能性。
    • 粘性瞄准主要在使用控制器时体现其效用,因为与鼠标相比,控制器的精确瞄准更具挑战性。
  2. Auto Aim(自动瞄准):

    • 自动瞄准是一种更直接的瞄准辅助。当玩家的瞄准准星接近敌人时,游戏可能会自动调整准星,直接对准敌人。
    • 这种机制通常在玩家射击时触发,游戏自动将准星移动到最近的目标上。
    • 自动瞄准提供了更明显的辅助,对新手玩家或是希望减轻瞄准难度的玩家更加友好。

总的来说,粘性瞄准提供了一种更微妙的辅助,它不会直接瞄准,而是减慢准星移动速度,帮助玩家进行精准瞄准。相比之下,自动瞄准提供了更直接的帮助,它会自动将准星对准目标,减少了玩家需要进行的瞄准操作。选择使用哪种瞄准辅助或两者的结合,取决于游戏设计师的意图和游戏的目标受众。

 

That’s the whole idea, actually. The best control scheme in my opinion is the one that offers maximum success to players while giving them a clear impression that they are doing all the work - any assisted aiming should be as invisible as possible.

辅助瞄准尽可能的无感知。

Unfortunately, “sticky aim” did not solve Relic Hunters Zero’s aiming completely, so I also had to look for an actual “auto-aim” solution that directly changed the aiming direction. That’s when it got tricky.

sticky aim没有彻底解决作者的问题,作者需要一种auto aim的方式。

My first instinct was to keep the “invisible” approach as I tried to emulate Destiny’s best-in-class aim system: a combination between sticky aim, large hitboxes and a gentle “nudge” of the aim towards valid targets.

作者第一种尝试是保持invisible”, sticky aim” + large hitboxes+ “轻推”摇杆

I spent a lot of hours trying to make it work before I gave up. Ultimately what I did was adding a third value to the aim direction: besides the “input” and the “view” values, I’d have an “auto-aim offset” that tried to compensate for differences between the player’s input and the target position. It slowly “nudged” the direction towards the enemies and at first it worked brilliantly! Accuracy was excellent and the feeling of control was great.

作者添加了第三个参数“自动瞄准偏移”,去弥补玩家的输入和目标朝向之间的差异,这样会慢慢推动到enemy的方向,初始感觉还不错。

The problem is that, in an analog control scheme, player directional input is always held, remember? So when the enemy dies or gets out of range, there is a gap there between input and in-game direction created by the auto-aim. My first solution was to smoothly “return” the aim offset to zero, but testing resulted in a lot of players reporting that the aim was “weird and moved by itself”.

但这样造成问题,当目标丢失或者死亡的时候,由于自动瞄准朝向和InputDirection存在差异,作者将当前AimDirection平滑的插值返回到InputDirection但测试反馈不理想,玩家表示AimSystem很奇怪,自己在动

Worse - at times players would fightagainst the auto-aim, and the laser sight would jitter up and down. My last resort was NOT removing the gap until the player let go of the stick - that is, after auto-aiming, there would be a constant offset between the input and the in-game direction. I hope this would maybe go unnoticed, but it wasnt the case. The gap could get pretty wide when engaging multiple enemies, and even if it didnt I was underestimating the precision of human muscle memory: players would try aiming at the same direction they just did a second before, and get different results. It was not acceptable.

更糟糕的是有时候玩家会“对抗”自动瞄准。激光线会上下抖动。作者让玩家松开摇杆之前不清理偏移,但是这回导致和多个enemies交战的时候,偏移会越来越大。作者低估了人类肌肉记忆的准确性:玩家会尝试瞄准相同的方向,却得到不同的结果,这是不可接受的。

The final solution? Breaking my first commandment. Turns out that using a relatively narrow auto-aim angle (about 30 degrees) and instantly snapping towards the enemy while changing the color of the laser sight was the best solution. Messing with the directional input was always unnatural, so trying to mask it was a fool’s errand - I found out that it was much better to clearly communicate to players that auto-aiming is taking place, and let it do its thing.

作者的解决方案:放弃一定需要平滑插值的准则 ,限定auto aim的相对角度是30度,并直接把瞄准线闪过去并修改颜色。明确的告知玩家当前是有自瞄发生的。

The narrow range makes sure that switching between targets can be done smoothly without the player feeling that the aim is “stuck” somewhere, and it gave that extra edge that controller input needed to be as accurate as the mouse. I’d prefer if the system was invisible, but that was the best solution I could come up with at the time. Also, players can disable both this auto-aim system and the sticky aim in the game’s Settings menu if they want to.

狭窄的范围确保切换目标的时候不会太突兀。玩家可以在设置中禁用自动瞄准和粘性瞄准。

 

More auto-aiming challenges

My first naive implementation of auto-aim had a minimum angle, and it just checked the angular difference between the player’s input and the target direction. If it was smaller than the minimum angle, I turned on the auto-aim. Simple, right? And also completely wrong.

作者的第一种自动瞄准方式,有个最小角度,检查玩家的inputJoystickTargetDireciton之间的角度差,如果小于最小角度,就打开自动瞄准,这简单但也是错误的。

What actually happens is that players would get MORE accurate the further they were from enemies. This is because the angular difference diminishes with the square of the distance (or something like that, I hope my mathematician friends dont hang me).

当距离越远,这个触发就会越频繁。因为随着距离的增加,角度会变小。

如下图,距离越远的时候,即使摇杆输入角度偏离更大了,也被触发自瞄了。

 

On the example above you can see that even though the player’s directional input and the angle towards the enemy was the same, the actual angular difference was far from it! Unfortunately, my sloppy code did not differentiate between these two cases, so I ended up with an auto-aim system that was either useless at close range or completely ubiquitous at long range.

I solved this by “projecting” the player’s directional input towards the target first, and then checking that final angle against my minimum auto-aim angle.

作者解决的方式 如下图:计算和目标圆交点的夹角。

Correct: different situations, different results

 

“A Good Feel Is A Hack”

I usually tell people - especially well-trained programmers that are cursed with having to work with me - that “A Good Feel Is A Hack”. When programming controls and feedback for games, it is tempting to try and make everything work with simple, all-encompassing rules, just like real-life.

The sad fact though is that real-life feels like s***

我经常告诉人们——特别是那些被诅咒必须和我一起工作的训练有素的程序员——“良好的感觉是一种Hack”。当为游戏编写控制和反馈时,我们很容易尝试使用简单的、包罗万象的规则,就像现实生活中那样。

可悲的事实是,现实生活感觉就像一坨屎

We want our games to feel smooth and larger than life, and often that will translate into a lot of special cases and ugly ifsin your otherwise pristine control code. Dont be afraid of them! This is general advice, so the best I can do is offer a few examples.

In Relic Hunters Zero, my camera tracks a sweet spotbetween the player position and the aiming position. It works great for mouse input (digital, remember?), but I had to make a lot of exceptions for analog sticks. For instance, there was a small and snappy camera movement that happened every time the player switched movement direction, and it was distracting - so I went into the code and wrote a special exception so that the camera would ignore the crosshair position unless the player was not moving OR not using the right analog stick OR the distance was below a certain threshold. Ugly, but effective.

我们希望我们的游戏看起来更流畅、更宏大,这通常会导致你的控制代码中出现许多特殊情况和丑陋的“如果”。不要害怕他!

例如,每当玩家切换移动方向时,都会出现一个小而快速的摄像机移动,这令人分心——所以我编写了代码并编写了一个特殊的例外情况,以便摄像机将忽略准线位置,除非玩家没有移动或没有使用正确的模拟操纵杆或距离低于某个阈值。丑陋,但有效。

Another example: my game has a digital crosshair as well as directional input (more on that on the next section). If you have auto-aim turned off or you use the subtle “assist” mode which uses the narrow angle I mentioned before, the digital crosshair stays at a distance to the player relative to the length of the stick’s directional vector. For the “full” auto-aim mode, however, I found out that it was better to communicate which enemy was being targeted, so I snap the digital crosshair to be straight on top of the enemy. This exception caused the camera to behave weirdly though, so I coded in yet another exception for the camera to ignore the crosshair when in “full” auto-aim unless the player is aiming or using the right stick.

In conclusion, a good game feel usually revolves around these small touches as you polish the rough edges of the experience. Players don’t care how elegant your code is, they just want smooth controls and feel - just make sure to document your “hacks” well and code maintenance won’t be a problem.

总而言之,优秀的游戏感觉通常围绕着这些小细节,因为你可以打磨游戏体验的粗糙边缘。玩家不关心你的代码有多优雅,他们只想要流畅的控制和感觉-只要确保你的“hack文档很好,代码维护不会是问题。

 

Digital Crosshair With Directional Input

I have just spoiled this in the previous sections, but Relic Hunters Zero has two types of aiming: regular and laser sight. Laser sight is 100% analog - it simply draws a red line corresponding to the input direction from the controller.

常规瞄准则试图通过数字准星模拟鼠标输入。我的做法是,准星与玩家之间有一个最大和最小的距离,这是由stickdeadarea之间的距离所决定的。这是一种让玩家感觉良好并帮助他们检查周围环境的简单方法,因为摄像机会随着准星与玩家角色的距离而移动。

Camera Ease-in and Ease-out

接下来文章内容 作者说了很多carmera平滑的事情。

总结起来就是插值。

Give The Game A Rest

Playtesting your game with complete strangers is extremely valuable!

让完全陌生的人测试你的游戏非常有价值!

I’m not saying that controls can’t be improved with player feedback - they definitely can, and you’ve just read about player testing helping me in pretty much all of the points of this article. A good rule of thumb I use (for feel and for everything else) is that if 3 or more people independently complain about something in your game, you most likely have a serious problem worth looking into.

如果3个或3个以上的人独立地抱怨你的游戏中的某些内容,那么你很可能存在一个值得调查的严重问题。(不包含相关的游戏制作人员,会带有主观印象)

Nevertheless, the designer is still the most important pair of eyes and hands when tuning the feel and controls of the game, so it’s very important to keep your perspective fresh. Take some time off (usually between a week and a month works for me), play other games, do other stuff, and then come back and check how well your controls and your feel are holding up

尽管如此,在调整游戏的感觉和控制时,设计师仍然是最重要的眼睛和手,所以保持视角的新鲜感非常重要。休息一段时间(对我来说通常是一周到一个月),玩其他游戏,做其他事情,然后回来检查你的控制和感觉是否良好

I’m not telling you to stop working on the game! Even when we are part of a team, it’s hard to have that luxury. As a solo developer, I usually shifted my focus elsewhere, coding a menu system, or a save system, or audio system - whatever kept me off the controls.

我并不是要你停止开发游戏!即使我们是团队中的一员,也很难有那种奢侈。作为一名独立开发者,我通常会将注意力转移到其他地方,编写菜单系统、保存系统或音频系统——任何让我远离控制的东西

If your game has support for both keyboard/mouse and gamepad, it’s also helpful to switch between them when developing. In Relic Hunters I would use only the mouse for a week, and then as I switched back to the controller I would notice several issues with it, and vice-versa. 

如果你的游戏同时支持键盘/鼠标和手柄,那么在开发过程中切换它们也是很有帮助的。在《Relic Hunters》中,作者将只使用鼠标一周,然后当我切换回控制器时,我将注意到它的一些问题,反之亦然。

 

posted @ 2024-01-29 00:00  sun_dust_shadow  阅读(47)  评论(0编辑  收藏  举报