移动输入

*此内容使用人工智能(Beta)翻译,可能包含错误。若要查看英文页面,请点按 此处

Roblox 会话的一半以上都在移动设备上播放,因此设计体验以满足广阔的受众时,请考虑跨平台的可访问性。您应该目标支持多种输入设备,包括 鼠标和键盘输入游戏手柄

当设计移动体验时,请考虑您的用户想在您的体验中使用的设备 orientierung,然后使用ContextActionService实现您的输入,以执行以下移动相关输入任务:

设备 Orientation

在手机和平板电脑上,设备的方向大多数影响用户体验和交互。例如,地图模式最佳操作为两个手指,而 portrait 模式可能会适合单手交互。

默认情况下,Roblox体验将以地图模式运行,允许体验在“左”和“右”之间切换,因为用户的设备旋转。但是,如果需要,体验可以锁定在特定方向。

定向模式

有五种不同的方向模式,包括两种感应器基于的模式和三种锁定模式。

传感器模式
地形传感器在默认情况下,Roblox 设置为“ always appear in landscape mode”(不是“ always in portrait mode”),设备检测到其物理方向,以确保体验视图总是朝上。
传感器该设备检测到其物理方向,以确保体验视图总是朝上,在需要时切换 between 景观和肖像模式。
锁定模式
左侧景观在有物理家园按钮的设备上,家园按钮位于显示器的左侧。在有虚拟家园/导航栏的设备上,其触摸区域位于显示器的底部。
景观右在有物理家园按钮的设备上,家园按钮位于显示器的右侧。在有虚拟家园/导航栏的设备上,其触摸区域位于显示器的底部。
肖像在有物理家园按钮的设备上,家园按钮位于显示下方。在有虚拟家园/导航栏的设备上,其触摸区域位于显示下方。

导向属性

当设置方向时,您可以设置开始方向在体验中方向当前方向

开始 Orientation

StarterGui.ScreenOrientation 为一个场景方设置默认方向。可接受的值包括:

因为这个属性影响所有新用户加入体验,您可以在 StarterGuiEnum.ScreenOrientation 内的 Studio 中设置其值。

在体验中导航

PlayerGui.ScreenOrientation 明确更改体验的方向为用户。当此属性设置为 Enum.ScreenOrientation 中的一个 LocalScript 枚列中时,体验会立即对准设置。这可能对于需要提供特定体验,例如锁定视图以便为小游戏锁定视图,很有用。

LocalScript 中的下一个代码示例将屏幕向导航画:


local Players = game:GetService("Players")
local playerGUI = Players.LocalPlayer:WaitForChild("PlayerGui")
task.wait(2)
playerGUI.ScreenOrientation = Enum.ScreenOrientation.Portrait

当前方向

PlayerGui.CurrentScreenOrientation 获取当前设备的方向。可能的值包括:

以下代码打印用户当前屏幕的方向:


local Players = game:GetService("Players")
local playerGUI = Players.LocalPlayer:WaitForChild("PlayerGui")
print(playerGUI.CurrentScreenOrientation)

角色移动模式

Roblox 提供几个 StarterPlayer 属性,您可以设置用户在移动设备上移动体验的方式。

您可以通过修改 StarterPlayer.DevTouchMovementMode 的值来设置移动控制协议对 Roblox 体验的计划,其中其中一个值为:

选项描述
ClickToMove用户只能通过点击目标位置来移动体验。此模式包括屏幕右下角的跳跃按钮。自动跳跃 总是在此移动模式中启用。
DPad
DynamicThumbstick一个动态缩略杆出现,其中用户初始向下按。 此模式包括屏幕右下角的跳跃按钮。 此是对于移动用户的默认用户设置,如果 UserChoice 已设置。
Scriptable禁用所有默认控件,允许您脚本您自己的控制方式
Thumbpad
Thumbstick移动的触摸棒位于屏幕的左下角。与 DynamicThumbstick 不同,触摸棒的位置是静的,不会改变位置,当用户触摸屏幕时。
UserChoice允许用户在体验设置菜单中选择他们想要的控制方式。这是体验的默认移动模式。

自动跳跃

StarterPlayer.AutoJumpEnabled 启用时,用户的角色在接近平台边缘时会自动跳过间隙。StarterPlayer.AutoJumpEnabled 默认为移动设备。

禁用 StarterPlayer.AutoJumpEnabled 以禁用此功能,并强制用户使用键盘快捷键来跳跃。

添加移动按钮

要添加移动按钮,请使用 ContextActionService:BindAction() 方法。

Class.ContextActionService:BindAction()|BindAction() 方法接受以下参数:

参数类型描述
动作名称字符串您所绑定的操作的标识符。您可以使用 actionName 与其他函数在 ContextActionService 中编辑绑定。
函数ToBind函数当指定输入触发时,该函数会调用。该函数接受三个参数:
创建触摸按钮boolean当真的时,在移动设备上运行时会创建屏幕上的按钮。
输入类型元组您想要将输入绑定到函数,例如从 Enum.KeyCode 中的枚数值。

您可以使用以下代码示例创建一个交互按钮,并且也接受 键盘游戏手柄 输入:


local ContextActionService = game:GetService("ContextActionService")
local function handleAction(actionName, inputState, inputObject)
if inputState == Enum.UserInputState.Begin then
print(actionName, inputObject)
end
end
-- 将功能绑定到
ContextActionService:BindAction("Interact", handleAction, true, Enum.KeyCode.T, Enum.KeyCode.ButtonR1)

移除移动按钮

要从屏幕上移除移动按钮,请使用您传递给 UnbindAction() 使用 actionName 字符串传递给 BindAction()

使用以下代码示例来解除之前创建的交互行动作的绑定:


-- 按名称取消绑定
ContextActionService:UnbindAction("Interact")

自定义按钮界面

您可以使用 ContextActionService 的多个函数来自定义由 BindAction() 创建的屏幕按钮。

按钮文本

要将文本标签更改为移动按钮,请使用 SetTitle() 使用 actionName 字符串和一个标题:


-- 将按钮标签设置为“聊天”
ContextActionService:SetTitle("Interact", "Talk")

按钮图像

移动按钮可以使用自定义图像,就像其他GUI按钮使用 Class.ContextActionService:SetImage()|SetImage() 方法。

使用以下示例代码设置一个按钮图像,并将资产 ID 替换为您选择的图像:


-- 设置按钮图像
ContextActionService:SetImage("Interact", "rbxassetid://0123456789")

按钮位置

默认情况下,屏幕右下角的新按钮位置会出现。 您应该仔细考虑放置按钮的位置,并且注意手指和手掌的位置。

使用以下示例代码来设置按钮的位置使用 SetPosition() 方法:


-- 设置按钮位置
ContextActionService:SetPosition("Interact", UDim2.new(1, -70, 0, 10))

context- dependent 输入

当开发为移动设备时,您可能会想要根据上下文更改单个按钮的行为。随着移动设备屏幕空间有限,请使用上下文按钮,以根据角色的能力执行不同的操作。

例如,您可以显示当用户站在靠近黄金箱子时显示的“收集”按钮:

使用以下代码示例创建一个标有“收集”的移动按钮,并且对于函数 collectTreasure 的:


local ContextActionService = game:GetService("ContextActionService")
local function collectTreasure(actionName, inputState, inputObject)
if inputState == Enum.UserInputState.Begin then
print("Collect treasure")
end
end
ContextActionService:BindAction("Interact", collectTreasure, true, Enum.KeyCode.T, Enum.KeyCode.ButtonR1)
ContextActionService:SetPosition("Interact", UDim2.new(1, -70, 0, 10))
-- 将图像设置为蓝色“收集”按钮
ContextActionService:SetImage("Interact", "rbxassetid://0123456789")

在游戏中的另一个时间,当用户站在 NPC 附近时,您可以单击“聊天”按钮。 在添加和移除现有按钮之后,您可以使用 ContextActionService:BindAction() 在现有互动操动作上使用,改变功能和按钮图像。

使用以下代码示例将现有按钮标签设置为“Talk”,并将其绑定到名为 talkToNPC 的函数:


ContextActionService:BindAction("Interact", talkToNPC, true, Enum.KeyCode.T, Enum.KeyCode.ButtonR1)
-- 将图像设置为黄色“聊天”按钮
ContextActionService:SetImage("Interact", "rbxassetid://0011223344")

检测其他设备

在跨平台体验中,我们需要知道用户的当前设备,以便调整用户界面和显示正确的键盘提示。

例如,如果用户靠近一个宝箱,并且有一些操作需要收集金币,那么您可以向移动用户显示一个“收集”按钮,而桌面用户则可以显示一个“T”键标志。

请记住,移动设备还可以有一个 鼠标和键盘游戏手柄 插入。它还可能有一个 touchscreen 已启用。 重要的是,请显示用户使用手机的预期输入选项。

电脑
移动端末

在这些情况下,您可以使用 UserInputService 来检测哪些输入设备已启用。如果多个输入设备已启用,请使用 UserInputService:GetLastInputType() 来获取用户最后使用的输入设备以显示在 UI 上。

您可以使用 ModuleScript,放置在 ReplicatedStorage 内,并命名为 UserInputModule ,以获取用户的输入类型,然后您可以适应用户体验的特定需求。

使用以下 ModuleScript 来检查是否启用了输入设备和最后使用的输入设备:


local UserInputService = game:GetService("UserInputService")
local UserInput = {}
local inputTypeString
-- 如果设备有键盘和鼠标,请假设这些输入
if UserInputService.KeyboardEnabled and UserInputService.MouseEnabled then
inputTypeString = "Keyboard/Mouse"
-- 如果设备有触摸功能,但没有键盘和鼠标,请假设触摸输入
elseif UserInputService.TouchEnabled then
inputTypeString = "Touch"
-- 如果设备有一个有效的游戏手柄,请假设游戏手柄输入
elseif UserInputService.GamepadEnabled then
inputTypeString = "Gamepad"
end
function UserInput.getInputType()
local lastInputEnum = UserInputService:GetLastInputType()
if lastInputEnum == Enum.UserInputType.Keyboard or string.find(tostring(lastInputEnum.Name), "MouseButton") or lastInputEnum == Enum.UserInputType.MouseWheel then
inputTypeString = "Keyboard/Mouse"
elseif lastInputEnum == Enum.UserInputType.Touch then
inputTypeString = "Touch"
elseif string.find(tostring(lastInputEnum.Name), "Gamepad") then
inputTypeString = "Gamepad"
end
return inputTypeString, lastInputEnum
end
return UserInput

一旦 UserInputModule 脚本在 place,使用 LocalScript 中的代码示例来获得用户的最后一次输入类型:


local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- 需要模块
local UserInputModule = require(ReplicatedStorage:WaitForChild("UserInputModule"))
local currentUserInput, inputEnum = UserInputModule.getInputType()
print(currentUserInput, inputEnum)