跨平台开发¶
Time:10 分钟
本文概述了在多个平台上进行 Roblox 游戏开发的最佳方法。
Roblox 理念¶
与其他游戏引擎不同,Roblox 本身就是跨平台的,玩家们可以在电脑上发现并游玩游戏,然后拿起手机并接着之前的进度继续游玩。在大多数情况下,Roblox 游戏应该可以在所有平台上游玩,而不是仅针对一个平台优化而在其他平台上“勉强能玩”。
手机第一¶
近期数据表明超过 55% 的 Roblox 游戏进程是在手机上进行的,所以您应该付出同等的努力来打造出色的手机游戏体验。在计划您的 UI 和控制时,请考虑以下几点:
UI 布局¶
即使 GUI 完美地适合电脑屏幕,在较小的手机屏幕上也不一定同样好用。例如,这个 GUI 中的颜色自定义砖块在手机上就变得太小太窄了:
相比之下,稍微重新设计 GUI 就能同时提升电脑用户和手机用户的体验:
保留区域¶
在移动设备上,/articles/customizing game controls#mobile-controls|默认控制
占据屏幕左下角及/或右下角的一部分。在设计游戏 UI 时,请避免将重要信息或虚拟按钮放在这些区域。
如果您的游戏使用默认UserChoice控制设置(/articles/customizing game controls#mobile-controls|reference
),屏幕上显示的控制可能会有少许偏差。在设计您的 UI 时请考虑到这个可能性。
拇指区¶
大多数手机玩家使用两个大拇指,一个控制虚拟摇杆/方向键,另一个控制跳跃键。根据设备尺寸和玩家的手部大小, 远离底部角落的按钮会很难按或者根本够不到,所以您应当避免将常用按钮置于绿色区域外。
适应性 UI¶
舒适的拇指区在手机与平板电脑上有所差别,因为平板电脑的屏幕更大。请记住一个放在屏幕顶部边缘 30% 以下的按钮在手机上可以轻易够到,但在平板电脑上几乎不可能够到。
相对跳跃按钮来设置自定义按钮的位置更为可靠。以下代码获取跳跃按钮的位置,并在上面创建一个占位的 ImageButton
按钮:
-- 获得玩家的跳跃键的参考
local player = game.Players.LocalPlayer
local PlayerGui = player:WaitForChild("PlayerGui")
local ScreenGui = PlayerGui:WaitForChild("ScreenGui")
local TouchGui = PlayerGui:WaitForChild("TouchGui")
local TouchControlFrame = TouchGui:WaitForChild("TouchControlFrame")
local JumpButton = TouchControlFrame:WaitForChild("JumpButton")
-- 获得按键的绝对尺寸和位置
local absSizeX, absSizeY = JumpButton.AbsoluteSize.X, JumpButton.AbsoluteSize.Y
local absPositionX, absPositionY = JumpButton.AbsolutePosition.X, JumpButton.AbsolutePosition.Y
-- 在跳跃键上创建新按键
local customButton = Instance.new("ImageButton")
customButton.Parent = ScreenGui
customButton.AnchorPoint = Vector2.new(0.5, 1)
customButton.Size = UDim2.new(0, absSizeX*0.8, 0, absSizeY*0.8)
customButton.Position = UDim2.new(0, absPositionX+(absSizeX/2), 0, absPositionY-20)
基于内容的 UI¶
移动设备上的屏幕空间非常有限,因此在游玩时应当只显示最关键的信息。例如,如果玩家有一个特殊动作可以打开门,那么无需把“开门”的按钮一直显示在屏幕上,而应当只在玩家接近门的时候才显示,并在玩家离开一段距离之后消失。
输入检测¶
有时必须获知玩家当前的设备以便调整 UI,显示行动按钮或提示等等。例如,如果玩家接近一只宝箱,并且有一个获取金币的动作,您可以在电脑端玩家的屏幕上显示 T 键图标,但在移动端玩家的屏幕上激活“收集”按钮。
移动端:激活收集按钮
电脑端:T 键提示
以下 ModuleScript
,置于 ReplicatedStorage
内并重命名为 PlayerInputModule,可用于获取玩家的输入类型,以便您根据上文的建议调整 UI 布局或内容。
local UserInputService = game:GetService("UserInputService")
local PlayerInput = {}
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 PlayerInput.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 PlayerInput
请注意脚本使用 UserInputService/GetLastInputType|UserInputService:GetLastInputType()
方法,而不仅是检查设备是否有触控之类的输入“能力”。这是因为电脑端玩家可能会倾向于使用键盘和鼠标,即使他们的电脑有触控屏,而您的 UI 应该遵从活动的输入类型。
在 PlayerInputModule 脚本就位后,您可以用如下方式从 LocalScript
获取玩家最后的输入类型:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- 对模块进行 Require
local PlayerInputModule = require(ReplicatedStorage:WaitForChild("PlayerInputModule"))
local currentPlayerInput, inputEnum = PlayerInputModule.getInputType()
print(currentPlayerInput, inputEnum)
***Roblox官方链接:跨平台开发