Roblox Guidebook知识库
简体中文 ⌄

开发 / ROBLOX

Roblox Studio 帮助按钮:电脑、手机与手柄

制作独立的本地帮助面板:安全区域、AnchorPoint、长文本换行、明确翻页与返回。包含准确属性、原创 LocalScript,以及尚未填写结果的测试计划。

为偶尔使用的帮助留出空间打开大图 ↗
原创示意图,不是 Studio 截图或安全区域测试。
更新日期:

可以打开,也能清楚返回的小帮助 #

想象一个独立练习项目:玩家看到场景和一个小“帮助”按钮。激活后出现说明,点击“关闭”恢复视野。这是屏幕界面,不是世界物体旁的交互提示。不需要 ProximityPrompt,也不需要服务器奖励或购买检查。我们只改变本地可见性和阅读位置。

本练习不修改网站作者的五款游戏。请在单独的 Studio 项目里搭建自己的结构。先写出三个预期:帮助能打开,文字能读到末尾,每种支持的输入都能关闭面板。大显示器上漂亮的矩形并不能证明这些条件。下文尺寸是起点,实际观察需要你自己记录;设计意图与已完成的设备测试必须分开。

1. 按准确名称搭建层级 #

在 StarterGui 内创建 ScreenGui,命名 HelpGui。它包含 TextButton HelpButton、Frame HelpPanel,以及普通 LocalScript HelpController。HelpButton 内放 UISizeConstraint ButtonBounds。HelpPanel 内放 UISizeConstraint PanelBounds、UIPadding PanelPadding、TextLabel Title、ScrollingFrame Body,以及三个 TextButton:ScrollUp、ScrollDown、CloseButton。在 Body 里放 TextLabel HelpText。

翻译可见标签时不要翻译实例名称。代码寻找 HelpPanel 和 Body,而不是名称相近的对象。StarterGui 是初始模板;带玩家的运行中,界面出现在该玩家的 PlayerGui。因此只检查编辑层级不够。如果 WaitForChild 一直等待,先核对准确名称和父对象,再改尺寸或替换事件。位置错误不是改颜色能解决的问题。

2. 为系统界面留下空间 #

HelpGui 设置 ScreenInsets=CoreUISafeInsets、ClipToDeviceSafeArea=true,并保持 Enabled=true。本练习 ResetOnSpawn=false 让界面在角色重生后保留,不代表跨次访问保存进度。当前安全区域设置考虑 Roblox 系统界面与设备区域。不要把 IgnoreGuiInset=true 当成通用办法:它改变边距行为,不会解决所有布局。

安全区域不知道你自己的计时器、地图或商店放在哪里,也不会自动把每个元素互相推开。先在没有自定义 HUD 的项目练习,再检查未来界面的真实邻居。如果另一 ScreenGui 挡住按钮,检查显示顺序和自己的层次。缩小字体不能消除别的覆盖层。先识别遮挡源,而不是同时试改全部属性。

3. 为什么示例把帮助放在上方中央 #

HelpButton 设置 AnchorPoint=(0.5,0)、Position=(0.5,0,0,12)、Size=(0.28,0,0,44)。ButtonBounds 设置 MinSize=(96,44)、MaxSize=(160,44)。这些是 HelpGui 区域内的练习起点,不是所有设备的最优尺寸。水平坐标跟随容器中心,上方间隔使用像素偏移。

偶尔阅读的帮助远离底部触控移动和跳跃区域。经常伸手到上方可能不舒服,平板尤其如此。所以这里是偶尔查看的说明,不是新的战斗按钮。也要检查自己的顶部计数器和聊天界面。如果玩家必须频繁打开帮助,应根据真实设备观察重新安排,并保留移动操作。处于安全区域,并不能证明拇指触达舒适。按钮用途决定检查重点。

4. 限制面板,不让它无限拉伸 #

HelpPanel 设置 AnchorPoint=(0.5,0.5)、Position=(0.5,0,0.5,0)、Size=(0.88,0,0.86,0)、Visible=false。PanelBounds 使用 MaxSize=(520,420)、MinSize=(0,0)。PanelPadding 四边各12像素。Scale 是容器比例,Offset 是额外像素;UDim2 的四个数字不能读成四个绝对屏幕坐标。

中央 AnchorPoint 在尺寸变化时保持中心。最大宽度避免简短提示变成大屏上的巨大横条。窄屏使面板缩小,因此内部内容需要单独检查。表格列出了其他对象的准确起始属性。如果可用高度装不下标题和按钮,应调整组合方式。约束和比例都不保证任意小窗口可用;容器适应与内容可读是两个需要一起检查的条件。

对象属性练习起始值
HelpGui · ScreenGuiScreenInsets=CoreUISafeInsets; ClipToDeviceSafeArea=true; Enabled=true; ResetOnSpawn=false; DisplayOrder=10; ZIndexBehavior=Sibling
HelpButton · TextButtonAnchorPoint=(0.5,0); Position=(0.5,0,0,12); Size=(0.28,0,0,44); Visible=true; Active=true; Selectable=true; ZIndex=2; TextSize=20; TextScaled=false; TextWrapped=true
ButtonBounds · UISizeConstraintMinSize=(96,44); MaxSize=(160,44)
HelpPanel · FrameAnchorPoint=(0.5,0.5); Position=(0.5,0,0.5,0); Size=(0.88,0,0.86,0); Visible=false; Active=false; Selectable=false; ZIndex=2; BackgroundColor3=(20,30,44); BackgroundTransparency=0; BorderSizePixel=0
PanelBounds · UISizeConstraintMinSize=(0,0); MaxSize=(520,420)
PanelPadding · UIPaddingPaddingLeft / Right / Top / Bottom = (0,12)
Title · TextLabelPosition=(0,0,0,0); Size=(1,0,0,28); TextSize=22; TextScaled=false; TextWrapped=false; BackgroundTransparency=1; Active=false; Selectable=false; ZIndex=3
Body · ScrollingFramePosition=(0,0,0,40); Size=(1,0,1,-96); CanvasSize=(0,0,0,0); AutomaticCanvasSize=Y; ScrollingDirection=Y; ScrollingEnabled=true; ScrollBarThickness=6; BackgroundTransparency=1; BorderSizePixel=0; Active=true; Selectable=false; ClipsDescendants=true; ZIndex=3
HelpText · TextLabelPosition=(0,0,0,0); Size=(1,-12,0,0); AutomaticSize=Y; TextSize=18; TextWrapped=true; TextScaled=false; TextYAlignment=Top; BackgroundTransparency=1; Active=false; Selectable=false; ZIndex=4
ScrollUp / ScrollDown / CloseButton · TextButtonAnchorPoint=(0,1); Position: (0,0,1,0) / (0.25,0,1,0) / (0.5,0,1,0); Size: (0.25,-6,0,40) / (0.25,-6,0,40) / (0.5,-6,0,40); Visible=true; Active=true; Selectable=true; TextSize=18; TextScaled=false; TextWrapped=true; ZIndex=3
*UDim2 = (XScale,XOffset,YScale,YOffset); AnchorPoint=Vector2(X,Y). Title/Body/HelpText: AnchorPoint=(0,0); Visible=true.
*HelpButton/ScrollUp/ScrollDown/CloseButton: BackgroundColor3=(230,120,65); BackgroundTransparency=0; TextColor3=(20,25,30); BorderSizePixel=0; AutoButtonColor=true.
*Title/HelpText: TextColor3=(245,247,250). Title.TextXAlignment=Center. HelpText.TextXAlignment=Left. HelpController.Enabled=true.

5. 让文字可读,把视窗与内容分开 #

HelpText 使用 TextWrapped=true、TextScaled=false、TextSize=18、AutomaticSize=Y。宽度跟随 Body,高度随文字增长。Body 使用 AutomaticCanvasSize=Y、CanvasSize=(0,0,0,0)、ScrollingDirection=Y、ScrollingEnabled=true。可见窗口保持有限,内容可以更高。上翻和下翻按钮提供另一条读取长说明的路径。

不要把整个长段落缩成几乎看不见的小字。先改说明:一个动作、预期结果、返回办法,再测试故意加长的练习版本。代码没有创建真实任务,可以替换示例文字。标题和按钮保持短标签。正文换行不能修复单独溢出的按钮;开头几行漂亮,也不能证明最后一句可访问。检查末尾时应真正移动阅读位置。

6. 选择本地示例的语言 #

UI_LANGUAGE 接受 ru、en、de、es、zh、ar,例如选择 "zh"。字典改变可见标签,HelpController 与 CloseButton 仍是对象名称。AutoLocalize=false 保留明确选择的字符串。这只是客户端练习语言,不是发布游戏中每位玩家的完整自动语言选择系统。

阿拉伯语正文右对齐,但混合文字、数字、标点与换行仍需视觉检查。德语 Schließen 和更长的说明可能揭示短英文 Close 看不出的错误。六种版本都要放在窄窗口检查,不要为了放大一个按钮让旁边按钮消失。真实本地化要保持动作含义、验证字体并使用独立翻译系统。小字典方便学习,却不能代替这些工作或保证所有文字自然适配。

7. 只连接一个 LocalScript #

把下面原创代码放入 HelpController。它找到准备好的对象,选择文字,设置导航顺序,并连接 Activated。主要操作 setOpen 改变 HelpPanel.Visible 与 HelpButton.Visible。打开面板时隐藏入口按钮,关闭时重新显示。没有 RemoteEvent、服务器请求或 DataStore 写入。

GuiNavigationEnabled 和 AutoSelectGuiEnabled 在独立练习里明确启用。它们影响客户端整体 GUI 导航,现有游戏要与已有菜单协调。不要为了修正名称拼写再复制一个处理器。本面板不停止角色,也不暂停服务器玩法。需要锁定移动的模态菜单是额外行为,必须另测。先让小结果容易从代码理解,再决定是否扩展,而不是把简单帮助变成完整菜单系统。

local GuiService = game:GetService("GuiService")
local gui = script.Parent
local help = gui:WaitForChild("HelpButton")
local panel = gui:WaitForChild("HelpPanel")
local title = panel:WaitForChild("Title")
local body = panel:WaitForChild("Body")
local bodyText = body:WaitForChild("HelpText")
local up = panel:WaitForChild("ScrollUp")
local down = panel:WaitForChild("ScrollDown")
local close = panel:WaitForChild("CloseButton")

local UI_LANGUAGE = "en" -- One chosen language for this local exercise.
local labels = {
    ru = {help="Помощь", title="Подсказка", up="Выше", down="Ниже", close="Закрыть", body="Это учебная панель. Прочитай подсказку и закрой её, чтобы снова видеть сцену. Здесь можно объяснить одно действие: что выбрать, какой результат ожидать и куда вернуться.\n\nЕсли текст не помещается, используй кнопки Выше и Ниже. Закрытие панели не завершает задание и не выдаёт награду."},
    en = {help="Help", title="Quick help", up="Up", down="Down", close="Close", body="This is a practice panel. Read the hint and close it to see the scene again. Explain one action here: what to select, which result to expect and where to return.\n\nIf the text does not fit, use Up and Down. Closing the panel does not complete a task or grant a reward."},
    de = {help="Hilfe", title="Kurze Hilfe", up="Hoch", down="Runter", close="Schließen", body="Dies ist ein Übungsfenster. Lies den Hinweis und schließe es, um die Szene wieder zu sehen. Erkläre hier eine Handlung: was auszuwählen ist, welches Ergebnis erwartet wird und wohin man zurückkehrt.\n\nWenn der Text nicht passt, nutze Hoch und Runter. Das Schließen erfüllt keine Aufgabe und vergibt keine Belohnung."},
    es = {help="Ayuda", title="Ayuda breve", up="Arriba", down="Abajo", close="Cerrar", body="Este es un panel de práctica. Lee la indicación y ciérralo para volver a ver la escena. Explica una acción: qué seleccionar, qué resultado esperar y adónde regresar.\n\nSi el texto no cabe, usa Arriba y Abajo. Cerrar el panel no completa una misión ni entrega una recompensa."},
    zh = {help="帮助", title="简短提示", up="上翻", down="下翻", close="关闭", body="这是练习面板。读完提示后关闭它,再次查看场景。这里可以解释一个动作:选择什么、预期结果是什么,以及之后回到哪里。\n\n如果文字显示不全,请使用上翻和下翻按钮。关闭面板不会完成任务,也不会发放奖励。"},
    ar = {help="مساعدة", title="إرشاد قصير", up="أعلى", down="أسفل", close="إغلاق", body="هذه لوحة تدريب. اقرأ الإرشاد ثم أغلقها لرؤية المشهد مجدداً. اشرح فعلاً واحداً: ماذا يختار اللاعب، وما النتيجة المتوقعة، وإلى أين يعود.\n\nإذا لم يظهر النص كله، استخدم أعلى وأسفل. إغلاق اللوحة لا يكمل مهمة ولا يمنح مكافأة."},
}
local words = assert(labels[UI_LANGUAGE], "Unknown UI_LANGUAGE")
for object, key in {[help]="help", [title]="title", [up]="up", [down]="down", [close]="close", [bodyText]="body"} do
    object.AutoLocalize = false
    object.Text = words[key]
end
bodyText.TextXAlignment = UI_LANGUAGE == "ar" and Enum.TextXAlignment.Right or Enum.TextXAlignment.Left
GuiService.GuiNavigationEnabled = true
GuiService.AutoSelectGuiEnabled = true
help.SelectionOrder = 1
up.SelectionOrder = 2
down.SelectionOrder = 3
close.SelectionOrder = 4
up.NextSelectionRight = down
down.NextSelectionLeft = up
down.NextSelectionRight = close
close.NextSelectionLeft = down
panel.Visible = false
help.Visible = true

local function fromGamepad(input)
    return input ~= nil and input.UserInputType.Name:match("^Gamepad") ~= nil
end
local function setOpen(open, controller)
    local selected = GuiService.SelectedObject
    panel.Visible = open
    help.Visible = not open
    if controller then
        GuiService.SelectedObject = open and close or help
    elseif selected == help or selected == up or selected == down or selected == close then
        GuiService.SelectedObject = nil
    end
end
local function scrollPage(direction)
    local height = body.AbsoluteWindowSize.Y
    local limit = math.max(0, body.AbsoluteCanvasSize.Y - height)
    local nextY = math.clamp(body.CanvasPosition.Y + direction * height * 0.8, 0, limit)
    body.CanvasPosition = Vector2.new(0, nextY)
end
help.Activated:Connect(function(input) setOpen(true, fromGamepad(input)) end)
close.Activated:Connect(function(input) setOpen(false, fromGamepad(input)) end)
up.Activated:Connect(function() scrollPage(-1) end)
down.Activated:Connect(function() scrollPage(1) end)

8. Activated 仍然需要到按钮的路径 #

Activated 支持鼠标点击、屏幕轻触,以及手柄激活已选择的 GUI 按钮。手柄先通过 Select 进入导航,找到高亮的帮助,再按下并松开 A。没有选中 GUI 时按 A,不保证打开。四个按钮都要 Selectable=true;背景和文字不应该抢走选择。

手柄打开后代码选中 CloseButton。向左到 ScrollDown,再到 ScrollUp;向右返回。手柄关闭会选回 HelpButton。鼠标或触控不会创建新的控制器焦点;用这些输入改变面板时,原先留在我们按钮上的选择被清除。普通帮助点击不应让其他菜单突然获得新焦点。这是示例的逻辑,尚需真实输入测试;网页结构图不能证明游戏中的高亮和导航已经正确。

按钮 → 面板 → 返回打开大图 ↗
本地界面,不改变服务器状态。

9. 理解阅读按钮的工作方式 #

scrollPage 读取可见区域高度,把 CanvasPosition 移动约该高度的80%。留下重叠部分帮助找到续读位置。坐标限制在零与内容高度减窗口高度之间。不需要滚动时上限是零。重复激活不应把文字推到内容末尾之外。

滚动仍是本地表现,不改变文字或任务状态。我们不承诺任何摇杆都会自动滚动选中的 ScrollingFrame;独立按钮给出明确的选择路线。另测鼠标滚轮和手机区域内拖动。关闭后阅读位置保留,因为代码不在每次打开时重设 CanvasPosition。如果希望每次回到开头,主动添加这一规则。可见性改变并不等于内容位置必须重置,也不能代替读者对行为的预期。

10. 先模拟,再检查真实屏幕 #

在 Studio 使用带玩家的 Test/F5。没有角色的 Run/F8 不能代替游戏中 PlayerGui 的检查。Device Simulator 有助于查看尺寸和方向;Controller Emulator 用于早期导航检查。菜单名称可能本地化。比较窄与宽视图、竖屏与横屏、短与长文本,以及打开和关闭状态。

之后检查手机和正常连接的实体手柄。触控上在帮助关闭时行走和跳跃,控制区域不应挡住入口。打开面板,找到关闭,不要在角落里寻找。模拟器不测量真实设备上的拇指舒适度,也不是手机性能试验。下表是尚未填写的计划:预期不能写成已经观察到的游戏测试结果。把版本、设备和实际现象填在同一条记录里,方便复查。

场景预期设备 / 版本 / 观察
电脑,点击打开与关闭可见性变化,不创建新 GUI 选择—
手机窄视图,两种方向帮助与关闭可达,不覆盖控制—
每种语言,长正文能到最后一行,旁边按钮可见—
Select → 已选 Help → A打开并选 Close;左到阅读按钮,右返回—
重复上翻与下翻CanvasPosition 保持在内容边界内—
手柄切换鼠标/触控,其他 GUI清除我们按钮的旧选择,不指定无关选择—
关闭、重开、重生代码不重设阅读位置;ResetOnSpawn=false—

11. 修复原因,记录检查边界 #

按钮不见时检查 Enabled、Visible、PlayerGui 层级与遮挡。出现却没反应时检查 LocalScript、名称、Active 和 Output。末尾文字消失时检查 HelpText 宽度、AutomaticSize、AutomaticCanvasSize,以及到最后一行的路径。手柄没有反应时先看高亮、Selectable 和 GuiService.SelectedObject,再考虑事件;不要直接替换成仅支持鼠标的事件。

材料已检查结构、原创图的 XML 与 Luau 语法;另用本地替代模型检查可见性转换和滚动边界。代码没有在 Studio、手机或实体手柄运行。保存练习版本和自己的观察。理想结果是可读帮助与可达返回;后续可以改善样式,但不要把界面状态混同服务器进度,也不要把尚未测试的设备当成证据。

原始资料

Roblox Creator Hub — Text & image buttons
ScreenGui
ScreenInsets
Position and size UI objects
GuiObject
UDim2
GuiButton
GuiService
Scrolling frames
Studio testing modes