欢迎光临散文网 会员登陆 & 注册

震惊!游戏里的鼠标加速竟要这样关?!职业哥都不懂的游戏小妙招!

2023-02-25 20:38 作者:勉強上手  | 我要投稿

起源引擎游戏的社区里经常能看到各种奇奇怪怪的鼠标参数设置,时不时就能看到一两个爆款视频发现新的“隐藏参数”。

为什么有这么多参数?哪些参数有用?由于V社起源引擎的游戏代码在各个时期有过多次完整的泄露,我们可以从源代码完全搞清楚这些乱七八糟的参数是怎么来的,到底有什么作用。

根据我读过的代码,大部分视频都是胡说八道,但居然也能火。

好为人师的我急了,写一点根据告诉大家:游戏选项里的原始输入就是真正的原始输入,瞎加参数反而可能会引入爆款视频里深恶痛绝的Windows鼠标加速。

当然,可能还是有很多人不信邪,油盐不进。

如果在你的认知里,游戏的逻辑是由源代码决定的,你又恰巧看得懂C++,那完全可以照着我的根据自己验证一下。

如果在你的认知里,除了源代码,游戏逻辑还受一些说不清道不明的玄学控制,那这篇文章就不用看了。

由于这些参数实在没什么意思,我也就懒得好好组织了,嫌太长或者看不下去的可以直接看最后的总结。


起源引擎中的两种参数

在游戏启动选项中我们见过两种参数,一种以"-"开头,一种以"+"开头,它们对应的是起源引擎中的两种参数。

  • "-"开头的参数是命令行参数,只能在启动选项中添加。

  • "+"开头的参数是起源引擎的控制台参数,可以在启动选项中修改,也可以通过cfg文件修改,也可以在游戏中的控制台里修改。

感兴趣的参考developer.valvesoftware.com/wiki/Command_Line_Options。


早期的起源引擎

早期的起源引擎是从Quake的游戏源代码改出来的,那个时代的Windows没有提供获取鼠标原始输入数据的方式,从鼠标的原始数据到游戏视角转动大概经历了这么一个流程:

鼠标将移动的原始数据发送给Windows

-> Windows根据鼠标原始数据和Windows鼠标设置的参数(可以用m_mousespeed, m_mouseaccel1和m_mouseaccel2来设置)计算鼠标指针的位移

-> 游戏引擎读取指针的当前坐标,减去屏幕中心坐标得到指针的XY偏移量,然后把指针归位到屏幕中心

-> 游戏引擎根据指针的XY偏移量、灵敏度(sensitivity)、游戏鼠标加速参数(m_customaccel*)、m_yaw(可以看我之前的文章)、m_pitch(竖直方向的m_yaw)等参数计算得到视角转动的角度

-> 根据转动角度更新视角


这一流程可以简单概括为:

鼠标原始数据->指针移动距离->视角转动角度


其中,[鼠标原始数据->指针移动距离]这一过程受Windows鼠标设置直接影响(Windows的设置可以通过游戏设置更改),[指针移动距离->视角转动角度]这一过程受游戏设置直接影响。


这两个过程中都可以引入鼠标加速,因此起源引擎中有两套和鼠标加速相关的参数:

  • 对发生在Windows里的 [鼠标原始数据->指针移动距离]:m_mousespeed, m_mouseaccel1和m_mouseaccel2用来设置与Windows鼠标指针加速相关的参数,也就是注册表HKEY_CURRENT_USER\Control Panel\Mouse位置的MouseSpeed, MouseThreshold1和MouseThreshold2

  • 对发生在起源引擎里的 [指针移动距离->视角转动角度]:m_customaccel开头的参数用来设置游戏引擎中的鼠标加速


早期Windows鼠标指针加速的完整逻辑是(参考systemmanager.ru/win2k_regestry.en/34683.htm):

  • 当鼠标回报点数小于MouseThreshold1时,指针移动距离就是鼠标回报点数

  • 当鼠标回报点数在MouseThreshold1和MouseThreshold2之间时,指针移动距离*2

  • 当鼠标回报点数达到MouseThreshold2时,指针移动距离*4


MouseThreshold是否起效受到MouseSpeed控制:

  • MouseSpeed = 0时两个MouseThreshold都不起效,指针移动距离就是鼠标回报点数

  • MouseSpeed = 1时只有MouseThreshold1起效,鼠标回报点数超过MouseThreshold1时指针移动距离翻倍

  • MouseSpeed = 2时MouseThreshold1和MouseThreshold2都起效,鼠标回报点数超过MouseThreshold1时指针移动距离翻倍,超过MouseThreshold2时指针移动距离乘四


可见,只要把m_mousespeed设置为0,Windows鼠标加速就会被起源引擎关掉。


起源引擎[指针移动距离->视角转动角度]中的鼠标加速逻辑说起来就比较复杂,概括一下大家想知道的:只要把m_customaccel设置成0,其他m_customaccel开头的参数都会失效,起源引擎此时不会引入鼠标加速。


更多的故事可以参考www.hltv.org/forums/threads/391206/m-mousespeed-1-or-0#r4945460中的35楼。

对起源引擎自带的鼠标加速逻辑感兴趣的可以看github.com/nillerusr/source-engine/blob/master/game/client/in_mouse.cpp中的ScaleMouse和ApplyMouse函数。


现在的起源引擎

后来,Windows的鼠标加速逻辑变了,起源引擎的默认逻辑也跟着变了。


Windows的鼠标加速逻辑变成了用控制面板中的“提供指针精确度”开关,根据一个加速曲线来控制指针移动的距离,不再是原来那种把指针移动距离乘二和乘四的简单逻辑了,MouseSpeed、MouseThreshold1和MouseThreshold2的意义也变了。


由于MouseSpeed这个参数在缺少信息的年代被起源引擎的某个开发者理解错了(可以参考上面hltv里的故事),现在的起源引擎默认是忽略m_mousespeed, m_mouseaccel1和m_mouseaccel2这三个参数的。但为了兼容性,在启动项中加入"-useforcedmparms"时还是会根据这三个参数修改Windows的MouseSpeed、MouseThreshold1和MouseThreshold2,其中:

- 如果只有"-useforcedmparms"这一启动项,则会把MouseSpeed改成m_mousespeed,把MouseThreshold1改成m_mouseaccel1,把MouseThreshold2改成m_mouseaccel2。

- 如果除了"-useforcedmparms"以外还加入了"-nonoforcemspd",则不会修改MouseSpeed,也就是忽略m_mousespeed

- 如果除了"-useforcedmparms"以外还加入了"-nonoforcemaccel",则不会修改MouseThreshold*,也就是忽略m_mouseaccel*

- 如果没有"-useforcedmparms",则m_mousespeed, m_mouseaccel*都会被忽略


由此可见,不加"-useforcedmparms"的情况下这三个参数就会被忽略,什么事都没有,加了反而可能启用Windows的鼠标指针加速。


感兴趣的参考github.com/nillerusr/source-engine/blob/master/game/client/in_mouse.cpp中的Init_Mouse函数。


另外,由于Windows现在提供了读取鼠标原始输入的接口GetRawInputData,起源引擎加入了新的选项m_rawinput来跳过指针数据这一步。当m_rawinput为1时,从鼠标的原始数据到视角转动的流程变为:

鼠标将移动的原始数据发送给Windows

-> 游戏引擎通过GetRawInputData读取鼠标发送的原始数据,作为XY偏移量

-> 游戏引擎根据指针的XY偏移量、灵敏度(sensitivity)、游戏鼠标加速参数(m_customaccel*)、m_yaw、m_pitch等参数计算得到视角转动的角度

-> 根据转动角度更新视角


可以简单概括成:

鼠标原始数据->视角转动数据


可见,当m_rawinput为1时,指针移动距离这一步被跳过了,因此与Windows鼠标指针相关的参数m_mousespeed, m_mouseaccel1, m_mouseaccel2全都没用,此时控制面板的鼠标设置也对游戏完全没影响。


感兴趣的参考github.com/nillerusr/source-engine/blob/master/game/client/in_mouse.cpp中的GetAccumulatedMouseDeltasAndResetAccumulators函数和github.com/nillerusr/source-engine/blob/master/inputsystem/inputsystem.cpp中的GetRawMouseAccumulators函数。


CSGO和Apex中的实验

由于泄露的源代码不是现在的源代码,Apex的引擎也和原版起源引擎不太一样,最好能做实验看看指针数据这一步是不是真的被跳过了。


我写了个简单的python脚本模拟Windows指针的运动。

  • 如果游戏还是通过指针数据转动视角,那这个脚本应该能让游戏视角转动。

  • 如果游戏跳过了指针数据,通过鼠标原始数据转动视角,那这个脚本应该就不能让游戏视角转动。

    import pyautogui

    import time

    

    while True:

        x, y = pyautogui.position()

        pyautogui.moveTo(x+100, y)

        print(x, y)

        time.sleep(0.5)

        x, y = pyautogui.position()

        pyautogui.moveTo(x-100, y)

        time.sleep(0.5)

        pyautogui.click()

        time.sleep(0.5)

    

这段脚本做的就是让指针每隔0.5秒左右移动100的距离,然后按一下左键。可以在Windows的命令行中用python运行这段脚本,再切换到游戏里看效果。


在CSGO中可以发现,当设置m_rawinput 0时,这段脚本既可以移动视角,也能开枪,说明此时游戏的视角转动是被指针数据控制的。当设置m_rawinput 1后,这段脚本就不会转动视角,只会开枪了。会开枪说明这段脚本生效了,不能转动视角说明此时游戏用的不是指针数据,而是鼠标原始数据。


尽管Apex是基于起源引擎开发的,但通过r5reloaded客户端的控制台我们可以发现Apex的控制台参数和起源引擎有很大的不同。如Apex中的灵敏度参数是mouse_sensitivity,CSGO中是sensitivity;Apex中没有m_mousespeed, m_rawinput等控制台参数;Apex中注释为"Mouse acceleration"的参数m_acceleration在起源引擎中是服务端用来控制移动加速的(参考github.com/nillerusr/source-engine/blob/master/game/server/triggers.cpp)。鉴于Apex的m_acceleration默认为0,在r5reloaded客户端的控制台中我们也找不到其他和鼠标相关,名字带accel的参数,我认为Apex游戏本身默认是不带鼠标加速的。那Apex用的是指针数据,还是鼠标原始数据呢?通过运行上面的脚本我们可以发现,在Apex中移动指针是不会转动视角的,因此Apex应该是直接用了鼠标的原始数据,把m_rawinput这个开关参数去掉了。


上面的实验还有一个丐版。我们知道控制面板的"选择指针移动速度"是可以更改指针速度的,我们只要把控制面板的"选择指针移动速度"分别拉到最低和最高,看对游戏有没有影响就知道游戏用的是不是指针数据了。不会python的可以在CSGO里把m_rawinput分别改成0和1自己试试,这个改法最快和最慢的指针速度之间差了112倍(参考liquipedia.net/counterstrike/Mouse_Settings),比爆款视频里若有若无的心理暗示高到不知道哪里去了。


总结

  • CSGO中想要没有加速的原始鼠标输入,只要设置m_rawinput 1和m_customaccel 0就行了,不要闲着没事在启动选项加-useforcedmparms。

  • Apex啥也不用加,有强迫症的可以确认一下自己的config里m_acceleration是不是0。

  • 鉴于在现代的Windows里获取鼠标原始输入是如此的简单,在新出的FPS游戏里,只要有鼠标原始输入的选项选上就行了。

最后,在这个问题上职业选手的参数没有参考价值,职业哥真不懂。


震惊!游戏里的鼠标加速竟要这样关?!职业哥都不懂的游戏小妙招!的评论 (共 条)

分享到微博请遵守国家法律