Roblox GuidebookBase de conocimiento
Español ⌄

Desarrollo / ROBLOX

Botón de ayuda en Roblox Studio: PC, teléfono y mando

Construye un panel local independiente con área segura, AnchorPoint, texto largo y regreso claro. Propiedades exactas, LocalScript original y un plan de pruebas sin resultados inventados.

Espacio para ayuda ocasionalAbrir imagen a tamaño completo ↗
Esquema propio, no captura de Studio ni prueba de área segura.
Actualizado:

Una ayuda pequeña que se abre y se cierra #

Imagina un proyecto de práctica independiente: el jugador ve la escena y un pequeño botón Ayuda. Al activarlo aparece una explicación; Cerrar devuelve la vista. Es una interfaz en pantalla, no una indicación sobre un objeto del mundo. No necesita ProximityPrompt, recompensa del servidor ni comprobación de compra. Solo cambiamos visibilidad local y posición de lectura.

Este ejercicio no modifica los cinco juegos del autor del sitio. Construye tu propia estructura en otro proyecto de Studio. Escribe primero tres resultados esperados: abrir la ayuda, leer hasta el final y cerrarla con cada entrada admitida. Un rectángulo atractivo en un monitor grande no demuestra esas condiciones. Los tamaños son puntos de partida; debes registrar las observaciones de las pruebas por separado.

1. Crea la estructura con nombres exactos #

Crea ScreenGui HelpGui dentro de StarterGui. Añade TextButton HelpButton, Frame HelpPanel y un LocalScript normal HelpController. HelpButton contiene UISizeConstraint ButtonBounds. HelpPanel contiene UISizeConstraint PanelBounds, UIPadding PanelPadding, TextLabel Title, ScrollingFrame Body y tres TextButton: ScrollUp, ScrollDown y CloseButton. HelpText es un TextLabel dentro de Body.

No traduzcas estos nombres al traducir las etiquetas visibles. El código busca HelpPanel y Body, no objetos con nombres parecidos. StarterGui es la plantilla; durante una sesión con jugador, la interfaz aparece en su PlayerGui. Mirar solo la estructura de edición resulta insuficiente. Si WaitForChild parece detenido, compara el nombre exacto y el padre antes de cambiar tamaños o sustituir el evento.

2. Reserva espacio para la interfaz del sistema #

En HelpGui elige ScreenInsets=CoreUISafeInsets y ClipToDeviceSafeArea=true. Mantén Enabled=true. ResetOnSpawn=false conserva esta interfaz al reaparecer en el ejercicio; no guarda progreso entre visitas. La configuración actual considera la interfaz principal de Roblox y zonas del dispositivo. No empieces con el consejo universal IgnoreGuiInset=true: cambia el comportamiento de los márgenes, pero no resuelve cualquier composición.

El área segura no conoce la posición de tu temporizador, mapa o tienda. Tampoco separa automáticamente todos los elementos en pantalla. Comienza sin tu propia HUD y después comprueba los vecinos reales de la interfaz prevista. Si otro ScreenGui cubre el botón, revisa orden de visualización y capas. Reducir letras no elimina una superposición ajena, y añadir margen sin entenderla puede ocultar el verdadero problema.

3. Por qué Ayuda está arriba y centrada #

HelpButton usa AnchorPoint=(0.5,0), Position=(0.5,0,0,12) y Size=(0.28,0,0,44). En ButtonBounds establece MinSize=(96,44), MaxSize=(160,44). Son valores iniciales dentro del área de HelpGui, no dimensiones óptimas universales. La coordenada horizontal sigue el centro del contenedor y la separación superior es una cantidad de píxeles.

Una ayuda ocasional queda apartada de las zonas inferiores de movimiento y salto en touch. Alcanzar la parte superior repetidamente puede resultar incómodo, sobre todo en una tableta. Por eso es una explicación que se consulta ocasionalmente, no un control de combate. Comprueba también contador superior y chat. Si hay que abrirla constantemente, revisa la posición con observaciones reales y conserva el acceso al movimiento. Estar dentro del área segura no demuestra comodidad del pulgar.

4. Limita el panel sin estirarlo indefinidamente #

En HelpPanel elige AnchorPoint=(0.5,0.5), Position=(0.5,0,0.5,0), Size=(0.88,0,0.86,0), Visible=false. PanelBounds utiliza MaxSize=(520,420), MinSize=(0,0). PanelPadding deja 12 píxeles en cada lado. Scale representa una parte del contenedor y Offset suma píxeles; los cuatro valores UDim2 no son cuatro coordenadas absolutas de pantalla.

El anclaje central mantiene el centro al cambiar el tamaño. La anchura máxima evita convertir una explicación breve en una franja enorme en el monitor. En una pantalla estrecha el panel se reduce y su contenido requiere comprobación aparte. La tabla indica valores iniciales exactos para los otros objetos. Si falta altura para título y botones, modifica la composición. Ni una restricción ni porcentajes garantizan una disposición usable en cualquier ventana imaginable.

Propiedades del objetoValores iniciales del ejercicio
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. Conserva texto legible y una zona de lectura #

HelpText utiliza TextWrapped=true, TextScaled=false, TextSize=18 y AutomaticSize=Y. La anchura sigue Body y la altura aumenta con el contenido. Body usa AutomaticCanvasSize=Y, CanvasSize=(0,0,0,0), ScrollingDirection=Y y ScrollingEnabled=true. El área visible sigue limitada y el contenido puede ser más alto. Arriba y Abajo ofrecen otro camino hasta una explicación larga.

No reduzcas un párrafo completo hasta hacerlo casi invisible. Mejora primero la instrucción: una acción, resultado esperado y regreso. Luego prueba una versión deliberadamente larga. El código no crea una misión real; sustituye el texto de ejemplo por el tuyo. Mantén cortas las etiquetas del título y botones. Ajustar líneas del cuerpo no arregla un botón desbordado, y ver las primeras frases no demuestra que la última sea accesible.

6. Elige el idioma de este ejemplo local #

UI_LANGUAGE admite ru, en, de, es, zh o ar. Elige "es", por ejemplo. El diccionario cambia etiquetas visibles; HelpController y CloseButton siguen siendo nombres de objetos. AutoLocalize=false mantiene las cadenas elegidas explícitas. Esto fija un idioma del ejercicio en el cliente, no una selección automática completa para cada jugador de un juego publicado.

El cuerpo árabe queda alineado a la derecha. Texto mixto, números, signos y saltos necesitan revisión visual. Schließen y una frase alemana más larga pueden revelar problemas ocultos por el corto Close. Comprueba las seis versiones en una vista estrecha. No ensanches un botón hasta hacer desaparecer al vecino. En una localización real se mantiene el significado de la acción, se comprueba la fuente y se usa un sistema de traducciones separado.

7. Conecta un único LocalScript #

Pega el ejemplo original en HelpController. Encuentra objetos preparados, elige etiquetas, establece orden de selección y conecta Activated. setOpen cambia HelpPanel.Visible y HelpButton.Visible. El panel abierto oculta su botón de apertura; al cerrar vuelve a mostrarlo. No hay RemoteEvent, solicitud al servidor ni escritura DataStore.

GuiNavigationEnabled y AutoSelectGuiEnabled están activados explícitamente para este proyecto independiente. Afectan a la navegación GUI del cliente en general; un juego existente debe coordinarlos con sus menús. No añadas otro controlador para arreglar un nombre mal escrito. Nuestro panel no detiene al personaje ni pausa el juego del servidor. Un menú modal que bloquee movimiento requiere comportamiento y pruebas adicionales. Mantén el primer resultado lo bastante pequeño para comprenderlo leyendo el código.

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 necesita un camino hasta el botón #

Activated sirve para clic, toque y activación con mando de un botón GUI seleccionado. Entra en navegación mediante Select, encuentra Ayuda resaltado, pulsa y suelta A. Pulsar A sin GUI seleccionado no promete abrir nada. Los cuatro botones necesitan Selectable=true; fondo y texto no deben capturar la selección.

Abrir con mando selecciona CloseButton. Hacia la izquierda se pasa a ScrollDown y después ScrollUp; a la derecha se regresa. Cerrar con mando devuelve la selección a HelpButton. Ratón o touch no crean nuevo foco del controlador; una selección anterior de nuestros botones se borra al cambiar el panel por esa entrada. Otros menús no deben adquirir foco nuevo por un clic de ayuda. Esta es la lógica del ejemplo, todavía pendiente de prueba con entradas reales.

Botón → panel → regresoAbrir imagen a tamaño completo ↗
Interfaz local; no cambia el estado del servidor.

9. Entiende los botones de lectura #

scrollPage mide la altura visible y mueve CanvasPosition aproximadamente el 80 por ciento de ella. La parte solapada ayuda a reconocer la continuación. La posición se limita entre cero y altura del contenido menos altura de la ventana. Sin necesidad de desplazamiento, el límite es cero. Repetir no debería llevar el texto más allá del final.

El movimiento es local y no cambia texto ni estado de tarea. No prometemos que cualquier stick desplace automáticamente un ScrollingFrame seleccionado: los botones separados ofrecen un camino explícito de selección. Comprueba además rueda del ratón y arrastre dentro del área en teléfono. Cerrar conserva la posición, porque el código no reinicia CanvasPosition en cada apertura. Si deseas volver al principio, añade esa regla conscientemente; no la deduzcas del simple cambio de visibilidad.

10. Emula primero y comprueba una pantalla real #

Inicia Test/F5 con jugador en Studio. Run/F8 sin personaje no sustituye la comprobación de PlayerGui durante el juego. Device Simulator ayuda con tamaños y orientaciones; Controller Emulator sirve para una primera revisión de navegación. Los nombres de menús pueden estar traducidos. Compara vistas estrechas y amplias, vertical y horizontal, texto breve y largo, estados abierto y cerrado.

Después comprueba un teléfono y un mando físico conectado normalmente. Camina y salta en touch con la ayuda cerrada: los controles no deben cubrirla. Abre el panel y encuentra Cerrar sin buscar las esquinas. El emulador no mide comodidad del pulgar en tu aparato ni rendimiento real del teléfono. La tabla siguiente es un plan sin completar. Una expectativa no debe presentarse como un resultado ya observado en una prueba de juego.

EscenarioExpectativaDispositivo / versión / observación
PC, clic para abrir y cerrarCambia visibilidad; no crea selección GUI nueva—
Teléfono, vista estrecha, ambas orientacionesAyuda y Cerrar accesibles; controles despejados—
Cada idioma, cuerpo largoÚltima línea accesible; botones vecinos visibles—
Select → Help seleccionado → AAbre y selecciona Close; izquierda lectura, derecha regreso—
Arriba/Abajo repetidosCanvasPosition dentro de límites del contenido—
Mando → ratón/touch, otra GUIBorra selección anterior de nuestros botones; no asigna otra ajena—
Cerrar, reabrir, reaparecerEl código no reinicia lectura; ResetOnSpawn=false—

11. Arregla causas y registra límites #

Si falta el botón, revisa Enabled, Visible, estructura PlayerGui y superposiciones. Si aparece pero no responde, comprueba LocalScript, nombres, Active y Output. Si desaparece el final, mira anchura de HelpText, AutomaticSize, AutomaticCanvasSize y acceso a la última línea. Si el mando parece inactivo, revisa resaltado, Selectable y GuiService.SelectedObject antes de reemplazar Activated por un evento solo de ratón.

Se comprobaron estructura del material, XML de nuestros dibujos y sintaxis Luau; un modelo local separado verificó transiciones de visibilidad y límites de desplazamiento. El código no se ejecutó en Studio, teléfono ni mando físico. Conserva versión del ejercicio y observaciones propias. El resultado deseado es ayuda legible con regreso accesible. El estilo posterior puede mejorarlo sin mezclar estado visual con progreso del servidor ni inventar evidencia sobre dispositivos sin probar.

Fuentes originales

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