为游戏添加控制器支持 | hyperPad Documentation
Logo

为玩家提供控制器,同时保留触控操作,并让玩家自行选择按键绑定。本教程将带你了解在 hyperPad 中完成设置的每个步骤。

你可以跟着教程从头做到尾,也可以直接跳到适合你游戏的部分:

示例中使用 Player、Move Joystick 和 Jump Button 等 Object 名称。请在自己的 Project 中选择对应的 Object。从头开始的移动示例是一个小型俯视场景。现有游戏示例则保留游戏当前的移动规则。

开始之前

通过设备的蓝牙或 USB 设置连接受支持的控制器。hyperPad 会检测已连接的控制器。你可以通过游戏自己的 UI 显示和分配这些设备。

你可以先构建行为,再连接控制器。检查移动、按键和多人游戏时,请使用实际设备。菜单中的控制器示意图展示的是布局;设备选择器则显示当前设备。

Controller Event 会根据实体控制器输入触发游戏行为。Map Control Inputs 则为游戏已有的输入添加实体设备上的替代操作。两者都可以选择 Player。Player 1 和 Player 2 是分配槽位。对于 Controller Event 和 Controller Status,Player 0 会监听任意控制器,可用于选择菜单。Map Control Inputs 使用 Player 1 或更高编号的玩家。

教学示意图中的白色连线表示执行下一个行为。将下方的白色连接点拖到下一个行为顶部的连接点。绿色箭头表示将一个输出拖到某个属性中。打开接收行为的属性,将来源行为的绿色输出图标拖到字段中;如果出现选择器,再选择指定的输出。只有一个输出的行为会直接填入字段。

圆角行为示意图是教学指南。属性面板和覆盖层屏幕是 hyperPad 深色模式下的实际截图。GIF 图注会标明哪些是原生录屏,哪些是绘制的教学动画。

从头构建控制器操作

1. 设置一个简单的移动场景

新建一个空 Scene。在 Main 图层上添加一个名为 Player 的 Graphic Object。选中它,将物理模式设为 Physics。在 Scene UI 上添加一个名为 ActionLabel 的 Label Object。为标签设置一些初始文本,例如 Press the bottom button。

点击地球图标打开 Global Properties。在物理设置中选择 Birds Eye View。将 World Gravity X 和 Y 设为 0。同时将 Air Resistance 设为 0。选择 Birds Eye View 后请检查一下,因为该预设可能会更改阻力。

深色模式下的 Global Properties,显示 Birds Eye View、世界重力为零以及空气阻力为零。

这样设置后,你就能观察摇杆控制的移动,而不会有重力把 Player 向下拉。Player 可以使用你自己的 Graphic。

2. 监听左摇杆

选中 ActionLabel,点击 Behaviors,然后从 Interaction → Controls 添加 Controller Event。不要为它连接输入白线。将 Player 设为 1,将 Control 设为 Left Stick,将 Event 设为 Value Changed。

Player 1 的 Controller Event,设置为 Left Stick 和 Value Changed。

深色模式下实际的 Controller Event 属性面板,显示相同设置。

摇杆发生变化时(包括回到中立位置时),Value Changed 都会运行。它的 x 和 y 输出表示摇杆方向,范围为 -1 到 1。

3. 将水平输入转换为速度

从 Logic 添加 Multiply Values。将它的标题改为 Scale X,这样就能区分两个计算。它仍然是 Multiply Values 行为。

将 Controller Event 底部的白色连接点连到 Scale X 顶部的连接点。打开 Scale X 的属性。将 Controller Event 的绿色输出图标拖到上方的计算字段,并选择 x。在下方字段中输入 5。保留两个字段之间的 times。

Controller Event 到 Scale X 的白色执行连线,以及拖入上方计算字段并乘以 5 的 x 值。

实际的 Scale X 属性面板,显示 Controller Event - x、times 和 5。

现在,摇杆的水平输入达到最大时,速度为 5。输入为一半时,速度为 2.5。

4. 设置两个移动轴

再添加一个 Multiply Values,并将它命名为 Scale Y。把 Controller Event 的 y 输出拖到上方字段。在下方字段中输入 5。

从 Physics 添加 Set Velocity。将 Object A 设为 Player。将 Keep X Velocity 和 Keep Y Velocity 关闭,以显示 x 和 y 字段。

按以下顺序连接白色执行链:Controller Event → Scale X → Scale Y → Set Velocity。将 Scale X 的 Result 输出拖到 Set Velocity 的 x 字段。将 Scale Y 的 Result 拖到 y 字段。

完整的移动行为链,包含三条白色执行连线和四条从输出拖到字段的绿色箭头。

实际的 Set Velocity 属性面板,两个 Keep Velocity 开关均已关闭,x 和 y 字段引用 Scale X 和 Scale Y 的 Result。

Set Velocity 使用结果之前会先运行两个计算。速度字段的单位是米/秒。两个轴使用相同的乘数,然后调整该数值来改变速度。

5. 检查摇杆回到中立位置时的情况

运行 Scene 并移动左摇杆,然后让它回到中心。同一个 Value Changed 事件会在摇杆回中时将 0 传给 x 和 y,因此计算会将两个速度轴都设为 0。

同一条 Value Changed 移动行为链会在摇杆回到中立位置时将速度设为零。

移动逻辑保留在这个事件中。重新绑定后,移动和停止操作都会使用新的摇杆。

6. 在设备或分配发生变化后停止移动

添加 Controller Status,设置为 Player 1 和 Event Changed。将它连接到另一个针对 Player 的 Set Velocity,并关闭两个 Keep Velocity 开关,将两个轴都设为 0。

Player 1 的 Controller Status 在发生变化后触发单独的零速度操作。

当 Player 1 的控制器断开连接或分配发生变化时,这会停止自定义移动。控制器断连由 Controller Status 处理。Value Changed 移动分支则处理正常的摇杆松开操作。

7. 添加按键操作

再添加一个根级 Controller Event,设置 Player 1、Bottom Button (A / ×) 和 Pressed。将它连接到 Set Label。将 Object A 设为 ActionLabel,并在 Text 中输入 Action!。

Bottom Button 的 Pressed 事件触发 Set Label,Object A 为 ActionLabel,Text 为 Action!。

深色模式下实际的底部按键 Pressed 事件属性。

运行 Scene。移动左摇杆,让它回到中立位置,然后按下底部面键。你应该能看到角色停止移动,按下按键时标签内容也会改变。确认这条连接正常后,你可以将 Set Label 换成自己的操作。

按键名称表示的是位置。 Bottom Button 在常见的 Xbox 布局中是 A,在 PlayStation 布局中是 ×。切换不同的受支持控制器品牌时,请保持相同的映射。

为现有触控游戏映射输入

如果你的游戏已经使用屏幕上的控制项来移动、跳跃或射击,请使用此方法。保留你已有的速度、动画、跳跃规则和射击设置。

8. 找到游戏使用的输入 Object

先通过触控玩游戏。打开包含 Joystick Controlled、Jump with Button 或 Shoot with Button 的 Behavior Tree。检查每个行为的 Object A 和 Object B。

对于这些行为,Object A 是摇杆或按键,Object B 是移动、跳跃或射击的角色。在本示例中,这些输入 Object 是 Move Joystick、Jump Button 和 Shoot Button。

教学指南中的 Joystick Controlled 属性显示 Move Joystick 为 Object A、Player 为 Object B。

这些行为各自都有一个 Input 输出,用来标识其输入 Object。映射时请使用该输出。角色的 Object ID 是另一个不同的输出。

9. 添加控制器移动

在同一个 Behavior Tree 中添加 Map Control Inputs,并将它作为单独的根行为。不要为它连接输入白线。将 Player 设为 1。

打开它的属性。将 Joystick Controlled 的绿色输出图标拖到第一个 Input 字段,并选择 Input。将 Device 保持为 Controller,再将 Mapped Control 设为 Left Stick。在 Name (optional) 中输入 Move。

将 Joystick Controlled 的 Input 拖入 Map Control Inputs,并选择 Left Stick 和 Move。两者之间没有白色连线。

Map Control Inputs 会向 Joystick Controlled 原本读取的同一个摇杆输入提供信号。移动设置仍由 Joystick Controlled 控制。

原生 GIF:将 Joystick Controlled 的输出拖到第一个 Controller Move 行,并选择 Input。

GIF 展示了已完成的 Input 引用,以及与之兼容的 Left Stick 选项。添加其他行时,使用相同的拖动操作。

10. 映射跳跃按键

点击 Map Control Inputs 上的 + Add Input。在弹出菜单中选择 Controller。将 Jump with Button 的绿色输出拖到新行的 Input 字段,并选择 Input。将 Mapped Control 设为 Bottom Button (A / ×),并将 Name 设为 Jump。

将 Jump with Button 的 Input 拖到用于底部面键的 Jump 映射行。

现在,底部面键会为 Jump Button 提供输入。跳跃次数、力度和其他跳跃设置仍由 Jump with Button 控制。

11. 映射射击按键

点击 + Add Input 并选择 Controller。将 Shoot with Button.Input 拖到 Input 字段。选择 Right Shoulder,并将该行命名为 Shoot。

将 Shoot with Button 的 Input 拖到用于 Right Shoulder 的 Shoot 映射行。

现在,一个 Map Control Inputs 行为中有三条控制器输入映射。保留移动、跳跃和射击行为原有的游戏逻辑连接。

12. 添加键盘替代操作

再点击三次 + Add Input,每次都选择 Keyboard。重复使用各个原有行为的 Input 输出。为每种替代操作使用相同的动作名称:

名称要拖入的 Input 输出Mapped Control
MoveJoystick Controlled.InputArrow Keys
JumpJump with Button.InputSpace
ShootShoot with Button.InputKey F

三条键盘输入行使用相同的 Move、Jump 和 Shoot 输入,并分别映射到 Arrow Keys、Space 和 Key F。

弹出菜单中有三个选项:Controller、Keyboard 和 Mouse。每行的 Mapped Control 选择器随后会根据所选设备显示兼容选项。你之后可以更改某行的 Device。

原生的 Add Input 弹出菜单,要求在添加行之前选择 Controller、Keyboard 或 Mouse。

之前添加的控制器输入行会保留在同一个 Map 中。现在应该共有 六行:三个控制器选项和三个键盘选项。

深色模式下实际的 Map Control Inputs 属性面板,显示 Move 的两种替代输入,以及 Controller 和 Keyboard 设备选项。

此截图重点展示两条 Move 输入行。请使用上面的值添加 Jump 和 Shoot 输入行。

13. 检查原有输入和新增输入

运行游戏。先测试原有的触控操作,然后测试 Left Stick、Bottom Button 和 Right Shoulder。如果使用键盘,再测试方向键、Space 和 F。

尝试同时按住触控按键和实体按键,然后先松开其中一个,再松开另一个。在所有按住状态的输入源都释放之前,输入会一直保持按下状态。

游戏运行时的 Controls 覆盖层显示 Controller、Keyboard 和 Mouse 选项卡,并列出一个设备的动作绑定。

下面会介绍如何添加此菜单。它的动作列表也便于检查动作名称和当前绑定。

映射自定义触控和键盘输入

14. 保留自定义触控动作

举个简单的例子,创建一个名为 Interact Button 的屏幕 Object 和一个名为 ActionLabel 的 Label。在一个 Behavior Tree 中添加 Started Touching,将 Interact Button 设为 Object A,并保持 Absorbs Touch 开启。将它连接到 Set Label,目标为 ActionLabel,文本设为 Interacted!。

如果你的游戏已有自定义按键,请直接使用它现有的触控动作。保留原来的白色游戏逻辑连线。

Started Touching 触发 Set Label。它的 Input 输出单独提供给控制器和键盘映射行使用。

点击此 Object,确认操作有效后再添加映射。

实际运行的示例中,点击 Interact 后 ActionLabel 显示 Interacted!。

15. 为自定义按键添加替代操作

添加一个单独的根级 Map Control Inputs,并设为 Player 1。将 Started Touching.Input 拖到第一行。保留 Device Controller,选择 Right Button (B / ○),并将该行命名为 Interact。点击 + Add Input,选择 Keyboard,并为其使用同一个 Input、Key E 和相同的 Interact 名称。

深色模式下实际的 Map Control Inputs 属性面板,Started Touching Input 映射到 Right Button 和 Key E,两行都命名为 Interact。

你也可以点击 Input 并直接选择 Interact Button。如果它的触控行为位于另一个 Behavior Tree,这种方法会很方便。请选择接收输入的按键 Object。

运行游戏,分别尝试触控、右侧面键和 E。每种操作都应该触发同一个现有动作。如果此 Object 还使用 While Touching 和 Stopped Touching,映射按键也会提供按住和释放状态。

请为所选输入选择兼容的映射。按键按下可以映射到其他按键或键盘键。滑动路径或多指手势则需要你编写对应的控制器游戏逻辑。

可选的鼠标替代操作: 点击 + Add Input 并选择 Mouse。为它使用 Interact Button 的 Input,并选择 Left Mouse Button。这样会提供相同的按键状态。指针位置和拖动逻辑仍应放在需要这些值的行为中。

16. 映射一个具体的 Keyboard Event

如果你的自定义动作已经从 Keyboard Event 开始,请保留该行为及其子行为。在本例中,将 Keyboard Event 设为 Event On Press 和 Key Spacebar,然后将它连接到 Set Label,文本为 Action!。

为 Player 1 添加 Map Control Inputs。将 Keyboard Event.Input 拖到第一行,保留 Device Controller,并选择 Bottom Button (A / ×)。将该行命名为 Action。

Keyboard Event 的 Spacebar 操作仍连接到 Set Label,它的 Input 输出则映射到底部控制器按键。

现在,Spacebar 和控制器按键都会触发同一个动作。此操作示例请使用单个具体按键。Any 键和按键序列事件无法确定一个可用于映射的具体按键。Keyboard Event 选择器将此按键称为 Spacebar;Map 选择器则将同一个按键称为 Space。

显示已连接的设备

17. 读取初始控制器数量

在当前菜单或覆盖层 UI 中添加一个名为 Controller Count 的 Label Object。打开它的 Behavior Tree。添加一个根级 Get Controllers,并将它连接到 Set Label。将 Object A 设为 Controller Count。把 Get Controllers 的 count 输出拖到 Text 字段。

原生 GIF:将 Get Controllers 的 count 设为 Set Label 的 Text。

标签会显示一个数字,例如 0。如果想在数字旁边显示文字,可以另外添加一个静态标题。此数量只包括控制器。键盘和鼠标属于单独的输入设备。

18. 在发生变化后刷新数量

在同一个 Behavior Tree 中添加 Controller Status,将 Player 设为 Player 0,将 Event 设为 Changed。将它连接到第二个 Get Controllers,再连接到第二个 Set Label,并将目标设为 Controller Count。将第二个 getter 的 count 拖到第二个 Set Label 的 Text 字段。

两个独立分支分别初始化和刷新 Controller Count。每个 Set Label 都使用各自 getter 的 count。

实际的 Controller Status 属性,设置为 Player 0 和 Changed。

两个分支都要保留在活动 UI 中。Get Controllers 会在 UI 启动时提供初始数值。Controller Status 会报告之后的连接和分配变化。没有连接控制器时,数量会保持为 0。游戏暂停时,Controller Status 也会接收连接和分配变化。保持它启用,设备一有变化,UI 就能立即更新。

如需完整的设备选择器,请使用下一节生成的 Controls 覆盖层。Get Controllers 还会提供设备列表,你也可以据此自行构建 UI。

添加 Controls 覆盖层并重新绑定输入

19. 打开 Controls 菜单

添加映射时,hyperPad 会创建一个可编辑的 Controls 覆盖层。在编辑器的 Overlays 列表中打开它。其中的 Object 构成控制器示意图、动作行、设备选择器和重新绑定按钮。

深色模式编辑器中的实际 Controls 覆盖层,Controller Body 已选中。

编辑器会显示隐藏的选项卡元素和监听元素的淡色轮廓。运行游戏时,这些元素会保持隐藏。

在游戏或暂停菜单中添加一个 Controls Button。为该 Object 添加 Started Touching,并将它连接到 Load Overlay。选择 Controls,将 Transition 设为 None,并保持 Pause 开启。这样,底层 Scene 暂停时,覆盖层仍可交互。

Controls 按钮加载生成的 Controls 覆盖层。

如果你完成了步骤 1–7 的自定义速度示例,请在 Load Overlay 之前插入 Set Velocity。目标设为 Player,关闭两个 Keep Velocity 开关,并将 x 和 y 设为 0:

自定义速度示例中,Started Touching 会先触发将速度设为零的 Set Velocity,再在 Pause 开启时加载 Controls。

先停止移动,可以避免摇杆回到中立位置后,该示例仍以最后的速度持续移动。对于这种自定义移动,请让所有暂停入口都经过同一个零速度操作,包括生成的 Menu 和 Escape 快捷操作、暂停按钮,以及下文的 Player 2 选择器入口。插入时,请保留模板中已有的事件设置和 Load Overlay 选项。

20. 让覆盖层适配你的游戏

选中一个覆盖层 Object,例如 Controller Body,然后打开它的 Graphic 属性。使用颜色选择器为它着色。模板使用带有预设色调的白色源图像,因此你可以在编辑器中更改颜色。也可以替换为自己的图像。

深色模式下实际的 Controller Body 色调选择器,显示模板使用的炭灰色。

更改布局时,请保留生成的行为引用以及 Done/Cancel 连接。编辑器中的标签只是占位内容。运行覆盖层时,会填入动作名称和当前绑定。未使用的行会消失;只有在所选设备的动作超过四个时,页面控件才会显示。

21. 选择玩家和已连接的设备

运行游戏并打开 Controls。选择 Player 1。步骤 21–23 中的 Move 和 Jump 名称来自映射现有游戏的示例。Controller Event 的绑定名称取自其行为标题;如果想在此菜单中使用不同名称,请为从头构建的事件设置清晰的标题。选择 Controller 选项卡。如果连接了多个控制器,可以使用设备名称旁的箭头将其中一个分配给所选玩家。如果该玩家没有控制器,也可以用箭头选择一个可用设备。

运行中的 Controls 覆盖层,显示 Player 1、输入设备标题、三个设备选项卡以及所选设备的动作列表。

菜单会显示运行时实际连接的设备。请使用平台的蓝牙或 USB 设置连接其他设备。在此处选择设备会在游戏中分配该设备。

选择 Controller、Keyboard 或 Mouse,即可查看对应设备的绑定。六行示例会在 Controller 和 Keyboard 选项卡下分别显示 Move、Jump 和 Shoot。每个选项卡只会列出你为该设备设置的替代输入。如果没有添加任何鼠标输入行,Mouse 选项卡会提示此游戏尚未设置鼠标控制。

Keyboard 选项卡显示当前的键盘绑定,不会混入控制器操作。

Mouse 选项卡只会显示你添加的鼠标替代输入。此示例将 Jump 映射到 Left Mouse Button。

Mouse 选项卡显示 Jump 映射到 Left Mouse Button。

输入相同、动作名称也相同的替代操作会共享同一个动作。控制器示意图会高亮显示当前选中的控制器绑定。

22. 让玩家重新绑定动作

将已连接的控制器分配给 Player 1 后,选择 Controller 选项卡。点击 Jump 行上的 Change。此时动作列表会替换为专门的监听提示。按下你想用于 Jump 的控制器按键。按下兼容按键后,列表会重新显示新的绑定。

键盘 Jump 绑定的监听提示,显示 Current: Space 和 Cancel 按钮。

此截图展示了 Keyboard 选项卡下 Jump 的同一个监听界面。当前绑定为 Space。

要更改键盘移动输入,请选择 Keyboard 选项卡,再点击 Move 上的 Change。按提示顺序按下四个不同的键:Up、Right、Down、Left。如果使用 WASD 移动,请依次按 W、D、S、A。

更改 Jump 的控制器按键不会影响它的键盘按键。按键绑定会等待另一个按键输入;移动绑定则会等待兼容的移动输入。

23. 取消、重置并继续游戏

监听过程中选择 Cancel,即可保留之前的绑定。按 Escape 或控制器上的 Menu 按钮也会取消输入捕获。使用 Reset selected 可将当前设备上高亮动作恢复为已设定的默认值。Reset all 会移除已保存的覆盖项,并将所选玩家的所有绑定恢复为预设值。

正常绑定列表显示 Reset selected、Reset all 和 Done。监听提示中会显示 Cancel。

选择 Done,松开刚刚捕获的输入,然后在游戏中再次按下。捕获到的输入在回到中立状态前不会传给游戏逻辑。绑定选择会针对当前 Project 和玩家保存。控制器分配只在当前会话中有效。

24. 如有需要,构建自定义重新绑定控件

生成的覆盖层已经提供了重新绑定 UI。如果想创建自己的 Change Jump 按钮,可以使用 Rebind Input。

作为此可选练习的变体,请将混合的 Map 拆分为两个 Map Control Inputs 行为,并将标题分别命名为 Controller Inputs 和 Keyboard Inputs。每个 Map 中保留一条 Move、Jump 和 Shoot 行,并使用相同的来源和实体设备选项。替换原来的混合 Map,避免它的各行作为另一份副本继续运行。

创建两个按钮 Object,分别命名为 Change Jump 和 Cancel Change,再创建一个名为 Jump Binding 的 Label。在包含这两个 Map 的同一个 Behavior Tree 中创建以下独立分支:

  • Change Jump 的 Started Touching → Rebind Input (Listen) → Rebind Input (Get Binding) → 为 Jump Binding 执行 Set Label。
  • 单独的根级 Rebind Input (Get Binding) → 另一个为 Jump Binding 执行的 Set Label,用于在 UI 启动时填充标签。
  • Cancel Change 的 Started Touching → Rebind Input (Cancel)。

对于 Listen 和两个 Get Binding 行为,将 Player 设为 1,通过 Input Behavior 选择实际的 Controller Inputs 行为,并选择 Binding Jump。Cancel 操作不需要目标。每个 Set Label 的 Text 都应接收它前面紧邻的 Get Binding 输出的 label。

自定义重新绑定示例展示了 Change、初始化和 Cancel 分支,以及 Get Binding 的标签拖入操作。

通过行为选择器选择 Controller Inputs 实例。在目标 Map 中保留一行 Jump,可以更轻松地在 Binding 选择器中选择。此示意图重点展示 Jump 行;Controller Map 中也要保留 Move 和 Shoot 行。

原生 GIF:将 Get Binding 实例的 label 输出拖到 Set Label 的 Text 字段。

捕获到新输入或取消操作后,Listen 会完成运行。随后连接的 getter 会读取当前保存的选项。添加更多 UI 反馈时,请参阅 Rebind Input 参考文档,了解成功、取消、提示和进度输出。

为每位玩家分配一个控制器

25. 为每位玩家提供独立的输入 Object

创建 Player 1 Character 和 Player 2 Character。每个角色都需要独立的摇杆和跳跃按键 Object。如果复制现有设置,请检查两个 Object 的选择是否正确。

在 Player 1 的游戏行为中,Object A 选择 Player 1 的输入 Object,Object B 选择 Player 1 Character。在 Player 2 的行为中,选择对应的 Player 2 Object。

为每位玩家的控制输入分别添加一个 Map Control Inputs。一个设为 Player 1,另一个设为 Player 2。这些行的 Device Controller 均保持不变。两者都可以将 Move 映射到 Left Stick,将 Jump 映射到底部按键。

两个独立的 Behavior Tree 将各自的摇杆和跳跃输入映射到 Player 1 和 Player 2,并使用不同的输入和角色 Object。

玩家槽位决定哪个已分配的控制器为该 Map 提供输入。所选输入 Object 则决定由哪个角色的游戏逻辑接收输入。如果其他玩家需要不同的输入 Object,请再添加一个 Map。

如果两位玩家共用一个键盘,请为他们分配不同的按键。不同玩家槽位之间共享键盘按键。

26. 打开控制器选择覆盖层

你可以使用生成的 Controls 覆盖层中的玩家选择器,以及 Controller 选项卡里的设备选择器。如果想创建自定义的“按下按钮即可加入”屏幕,请创建一个名为 Player 2 Selection 的覆盖层。添加一个 Label,提示 Player 2 按下控制器底部按键。

在菜单中添加一个 Choose Player 2 Controller 按钮。将它的 Started Touching 连接到 Load Overlay。选择 Player 2 Selection,将 Transition 设为 None,并保持 Pause 开启。

Choose Player 2 Controller 按钮以 Pause 开启的状态打开 Player 2 Selection。

将下一步中的选择行为添加到此覆盖层内的提示 Label 上。只有在选择 UI 打开时,它们才应该运行。

27. 分配刚才按下按键的控制器

在 Player 2 Selection 中添加 Controller Event,设置 Player 0、Bottom Button (A / ×) 和 Pressed。将它连接到 Assign Controller,并将 Player 设为 2。

打开 Assign Controller 的属性。将 Controller Event 的 deviceID 输出拖到 Controller ID。用这个实时输出识别刚才按下按键的设备。

Controller Event Player 0 为 Assign Controller Player 2 提供 deviceID。

原生 GIF:为 Assign Controller 的 Controller ID 字段选择 deviceID。

Player 0 会监听已分配和未分配的控制器。Assign Controller 会将所选设备分配到 Player 2 槽位,并替换该槽位先前分配的设备。

28. 成功后关闭选择器

将 Assign Controller 连接到 If。将 Assign Controller 的 success 输出拖到 Value A。选择 Is Equal To,并在 Value B 中输入 1。

将 If 的底部匹配输出连接到 Close Overlay。将 Transition 设为 None,开启 Unload,并保持 Resume All 关闭。在这个简单示例中,If 右侧的不匹配输出留空即可。

完整的选择行为链:Controller Event、Assign Controller、If success 等于 1,以及从底部匹配路径触发的 Close Overlay。deviceID 和 success 输出的拖入操作分别展示。

分配成功后,选择覆盖层会关闭并卸载。分配失败时,覆盖层会继续打开。卸载后会移除 Player 0 的选择监听器,因此正常游戏操作不会重新分配控制器。

29. 检查两位玩家

打开选择器。按下要分配给 Player 2 的控制器上的底部按键,然后等菜单关闭后再松开。分别测试 Player 1 和 Player 2。

Player 1 和 Player 2 的独立映射行为使用相同的实体按键位置,但输入 Object 不同。

使用两个实际控制器检查多人独立操作。如果只有一个控制器,也可以检查重新分配功能。根据游戏需要,为更多玩家添加槽位和映射。可连接的设备数量取决于平台和硬件。

新连接的控制器会获得第一个空闲的正数槽位。玩家可以通过选择器更改这个分配。设备 ID 仅在当前会话中有效,因此请使用事件提供的 deviceID,不要保存手动输入的 ID 供后续会话使用。

添加振动反馈

30. 在按键操作中添加振动

返回步骤 7 中创建的 Controller Event 和 Set Label。保留两者之间的白色连线。按键仍应将 ActionLabel 设为 Action!。

从 Interaction > Controls 添加 Vibrate。将 Set Label 底部的白色圆形连接点连到 Vibrate 顶部的白色圆形连接点。设置以下属性:

  • Player: 1。
  • Vibrate: Controller。
  • Intensity (%): 70。
  • Duration (ms): 150。

步骤 7 中的 Controller Event 连接到 Set Label,目标为 ActionLabel、文本为 Action!;再连接到 Vibrate,设置为 Player 1、Controller、70% 和 150 ms。

保留原有按键操作连接。它后面的白色连接会触发振动。

将受支持的控制器分配给 Player 1 后运行游戏。按下底部面键。标签会改变,控制器也会短暂振动。支持触觉反馈的已配对 iPhone 也可以使用相同设置。

对于现有触控游戏,请在需要产生反馈的游戏事件或操作后添加 Vibrate。原始输入及其映射的控制器替代输入都可以连接到同一个 Vibrate 行为。振动不需要新增 Map 行。

多人游戏中,请将 Player 设为接收反馈的玩家。你也可以将该玩家 Controller Event 中大于 0 的 playerIndex 输出拖到 Vibrate 的 Player 字段。同时保留白色执行连线。

绘制动画:将 Controller Event 的 playerIndex 输出拖到 Vibrate 的 Player 字段。

教学动画。绿色引用提供玩家编号,白色连线触发振动。

振动强度范围为 0 到 100%。持续时间单位为毫秒,因此 1000 ms 就是一秒。将任一数值设为 0 即可停止。Vibrate 发出请求后,会立即运行下一个已连接的行为。

无法振动的控制器仍可能正常接收输入。请参阅 Vibrate 参考文档,了解目标设备选项、success 输出和平台支持情况。玩家可以在 Controls 覆盖层中重新绑定游戏操作;振动则是附加在游戏动作上的反馈。

检查完成后的游戏

尝试操作检查内容
不触摸屏幕,直接重新开始已映射的控制器和键盘输入可立即使用。
使用原有触控 UI移动、跳跃、射击和自定义动作仍遵循你设定的规则。
松开摇杆和按键持续输入的动作会停止。自定义速度示例的两个轴都会回到 0。
断开或重新分配控制器状态 UI 会刷新。自定义移动会通过 Status 分支停止。
更改一个绑定,然后取消另一个更改已保存的选项有效。取消操作会保留原有选项。
重置并重新打开 Project根据需要恢复默认值。已保存的选择会保留在 Project 和玩家中。
打开并关闭 Controls游戏暂停时,覆盖层仍可交互。点击 Done 后游戏继续。
使用两个控制器进行游戏每个控制器都能操作分配给对应玩家的 Object。
触发每位玩家控制器的振动在受支持的硬件上,正确的玩家会收到短暂振动。反馈不可用时,游戏仍会继续。

如需查看各项属性和输出的说明,请参阅 Map Control Inputs、Controller Event、Controller Status、Get Controllers、Assign Controller、Rebind Input 和 Controls Overlay。

有关设备触觉反馈、控制器反馈和已配对 iPhone 的信息,请参阅 Vibrate。