Steamworks 文献库
游戏内操作文件

概览


开发人员必须为自己的游戏提供输入配置的游戏内操作(IGA 文件),定义游戏输入配置的操作、操作集,与基础结构。 本文将说明此文件的整体结构,并提供各种游戏的具体示例。

示例文件


手动创作游戏内操作文件

首先下载上文样例中给出链接的第一份游戏内操作(IGA)文件。 然后,在 Steam 文件夹内创建一个“controller_config”目录,通常路径为 C:/Program Files (x86)/Steam/controller_config,将文件放进目录。 Steam 文件夹中会有名称非常相似的文件夹,请确保您将其放入了“controller_config”中,而非“controller_base”中。 将文件重命名为:“game_actions_X.vdf”,其中 X 是您游戏的 Steam AppID。 若您不知道您游戏的 Steam AppID 是什么,登录您的 Steam 合作伙伴站点就可以找到。

现在,在您常用的文本编辑器中打开该文件。 该文件采用标准的 Valve 格式,称为 KeyValues,是一种简单易读的格式。 您也可以下载我们的游戏内操作文件模板或 Portal 2 IGA 作为参考,也许会有帮助。

从一款使用 Steam 输入 API 的现有游戏中生成一份 IGA 文件


如果您将任何一款 Steam 上的游戏的配置保存为“本地”配置,那么您可以依循以下路径找到对应的文件:
[Steam 路径]\UserData\[您的用户 ID]\241100\remote\controller_config\[appid]\[保存名称].vdf

下图是本文作者《守护者冒险》的本地配置在普通 Windows 10 电脑上的存储位置:

whereisvgf.png

请注意这些文件不是开发人员上传的 IGA 主文件的精确复本,但是您可以通过查看直接从主文件中提取出的“actions”和“localization”两个数据块,大致了解原始结构。

请点击以下链接下载上图所示的 #library_controllersavedefaulttitle_0.vdf 文件,将其与《守护者冒险》的 IGA 主文件对比会很有帮助。

IGA 格式


IGA 文件采用 VDF 文档格式,VDF 是 Valve 自有的数据格式,使用键值对字符串来创建结构化对象数据。

基本框架


该文件的基本结构是由一个名为“In Game Actions”的包装器对象,与名为“actions”和“localization”的两个子对象所组成。

"In Game Actions" { "actions" { } "localization" { } }

操作集

让我们来仔细看看“actions”对象。 该对象包含您的操作集。 “actions”对象的结构如下:
"actions" { "ActionSetNameGoesHere" { "title" "#TitleGoesHere" "StickPadGyro" { } "AnalogTrigger" { } "Button" { } } }

在上述示例中,用户只应替换“ActionSetNameGoesHere”“#TitleGoesHere”这两个字符串,其余皆为应保留的关键词。

用来替换“ActionSetNameGoesHere”的值应为您在 Steam 输入 API 中使用的操作集的名称。 用来替换“#TitleGoesHere”的值则为您之后在文件中的“localization”部分中使用的本地化标记。 请注意这里需要 # 符号。

每一个操作集都应具备独一无二的字符串名称,想新增操作集时,只需在容器对象“actions”的范围内创建更多对象。 请勿包含逗点或方括号,这是 VDF 格式,而非 JSON。

有三个子对象可存在于每个操作集对象中: “StickPadGyro”“AnalogTrigger”“Button”。 您只能定义这三个子对象,它们同时也将是容纳您的个人操作定义的容器。 然而,您并不需要提供全部这三个类别。

此结构完全有效,如下所示:
"actions" { "ActionSetName1" { "title" "#Title1" "AnalogTrigger" { } "Button" { } } "ActionSetName2" { "title" "#Title2" "StickPadGyro" { } } "ActionSetName3" { "title" "#Title3" "Button" { } } }

StickPadGyro

此操作集数据块用于可有最多两个动作轴的模拟操作,您可能会想将其绑定至游戏、触控,或陀螺仪上。 此外,任何您想通过鼠标或其他类似物进行操控的操作,也应包含在内。

AnalogTrigger

此操作集数据块用于只有一个动作轴的模拟操作,您可能需要将其绑定至一个模拟扳机键。

按键

此操作集数据块为纯数字操作,仅报告开或关两种状态。 尽管此数据块名称为“按键”,但数字操作可与任何物理输入绑定,包括原先设计用于输出模拟数据的摇杆、触控板等。

操作


IGA 文件只有在定义操作之后,才会实际有效,因此让我们来添加一些吧!

StickPadGyro 操作

我们从添加一些 StickPadGyro (双轴模拟)操作开始。 来一些移动角色的操作如何?我们称之为“Move”。再来一个控制视角的,叫作“Camera”。

"actions" { "FPSControls" { "title" "#Set_FPSControls" "StickPadGyro" { "Move" { "title" "#Action_Move" "input_mode" "joystick_move" } "Camera" { "title" "#Action_Camera" "input_mode" "absolute_mouse" } } } }

由此可以看出 StickPadGyro 操作的抽象结构为:
"ActionNameHere" { "title" "#ActionTitleHere" "input_mode" "<analog_mode>" }

在这个结构中,用户可自行编辑的值只有我标出来的“ActionNameHere”、“#ActionTitleHere”及“<analog_mode>”。 以上三个对象分别对应于 Steam 输入 API 用的操作字符串名称、此文件本地化部分中使用的本地化键值,以及控制如何处理与解释模拟数据的输入源模式。

StickPadGyro 操作的“input_mode”属性有两个可能的值:

  • joystick_move
  • absolute_mouse

将被转换为摇杆(围绕中心点的持续偏转)操作的值应使用“joystick_move”,更灵活的一般目的模拟操作则应使用“absolute_mouse”。 不确定时,则使用“absolute_mouse”

joystick_move”与 “absolute_mouse”对比

在为第一或第三人称游戏或任何主要使用光标的游戏创建视角输入时,您应永远使用“absolute_mouse”类型,把它当成鼠标来响应差异,这一点非常重要。

API 会自动为摇杆输入进行正确的设置,因此如果您的视角应用于具有完全死区/反应曲线等的模拟摇杆(PS4/Xbox 类型),而您可以在默认配置中对其进行指定, 您仍可得到摇杆的可调整输入。 同样的输入也可用于摇杆、触控板、动态控制陀螺仪(Steam 控制器或 PS4)以及未来对鼠标的支持。

视角不应使用基于“”的输入方式,因为无法为触控板、陀螺仪、鼠标、运动控制进行反向映射来获得有用的 1:1 数据。

同理适用于基于光标的输入。“absolute_mouse”作为光标在基于游戏杆的输入也能顺利运作。因此,就算您需要基于摇杆的光标,也不必自行创建。

您可以选择将低级鼠标事件与您的模拟数据一同送出。 您的游戏无法区别这种鼠标事件与您的操作系统产生的鼠标事件。 执行方法为添加值“os_mouse”,并将其设为 1。

示例如下:
"StickPadGyro" { "Mouse" { "title" "#Action_Mouse" "input_mode" "absolute_mouse" "os_mouse" "1" } }


AnalogTrigger 操作
AnalogTrigger 操作是可以绑定在扳机上的单向模拟操作。 如果您使用简单的扳机阈值来执行诸如开枪或启动“瞄准射击(Aim Down Sights)”模式之类的操作,您可能需要使用按钮操作而不是模拟扳机操作,以便用户在重新绑定时具有更大的灵活性。

AnalogTrigger 操作在重新绑定 UI 中有一个可配置的死区,并可在 0 - 1.0f 内重新缩放。 带有数字扳机键的控制器(如 Nintendo Switch Pro 控制器)将发送 0 或 1.0,因此您可能需要检查下您是否有依赖于随时间渐变的扳机的游戏玩法代码。

AnalogTrigger 操作具有简单的格式,以操作名称为键,以本地化标记为值。 如下所示:
"AnalogTrigger" { "AccelerationAxis" "#Action_Accelerate" "BreakingAxis" "#Action_Brake" }

按键操作

按键操作也有相似的格式,使用操作名称和本地化标记:
"Button" { "digital_action_1_name_here" "#DigitalAction1TitleHere" "digital_action_2_name_here" "#DigitalAction2TitleHere" }

必要时,您可以定义原生的低级输入硬件事件(比如原生鼠标点击),与操作本身同时触发。 这适用于一些极端情况。比如,您的游戏依赖于一个深达七层且非常讲求细节的输入堆栈,而该堆栈对待来自您应用程序层的模拟鼠标事件的方式与对待操作系统直接产生的事件方式一直都不太一样

"Button" { "simple_click" "#simple_click" "fancy_click" "#fancy_click, mouse_button LEFT" }

每次“fancy_click”操作被触发时,以上程序代码就会让游戏发出一个值为 true 的操作系统层级的鼠标左键事件。

警告!

不论任何时候,您都不应该依赖这一项技巧为游戏操作强制绑定某些固定的输入。 那将违背了整个“操作、非输入”的范例目的,无法让用户全面控制自身的配置。 如果您在少数特殊情况之外也在使用上述功能,说明您有可能使用过度了。

操作集层

除了操作集外,您也可以使用操作集层为活跃的操作集逐步叠加变更。 您可以使用操作集层处理一般模式的特殊实例(如在 OnFoot 控制上添加一个狙击手层),或是用来处理正常游戏中跳出的游戏内 UI(如投票屏幕)。 操作集层要在自己的部分声明,如:
"action_layers" { "IngameModalLayer" { "title" "#Layer_IngameModal" "legacy_set" "0" "set_layer" "1" "parent_set_name" "InGame" "AnalogTrigger" { } "Button" { "Modal_Accept" "#Action_Modal_Accept" "Modal_Decline" "#Action_Modal_Decline" } } }

本地化


IGA 主文件除了操作集定义外,还应该包含一个本地化部分。 本地化对象下的各个子对象会是 Steam 支持的任一语言字符串。 请确认当中至少有一个程序块含有英文的操作标题。

"localization" { "english" { "move" "Move" "camera" "Camera" } }

注意:属性的名称应与先前部分中确定的本地化键对应,只是没有“#”符号。

想新增更多语种,只需添加更多语言的程序块,让每个语言的程序块包含本地化文本即可。

"localization" { "english" { "move" "Move" "camera" "Camera" } "spanish" { "move" "Mover" "camera" "Cámara" } "norwegian" { "move" "Bevege" "camera" "Kamera" } }
每种语言的标记应与“API 语言代码”值匹配,例如:“schinese”表示简体中文。 所支持的语言的完整列表可以在 此处找到。

Steam 如何使用您的 IGA 文件


您的 IGA 主文件只会在开发期间创建(但仍应该进行保存、维护,并将其存储在您的版本控制中等)。 当您在开发阶段为您的游戏创建官方输入配置时,Steam 客户端会使用您的 IGA 主文件生成起始模板。