Widgets de Studio

*Este contenido se traduce usando la IA (Beta) y puede contener errores. Para ver esta página en inglés, haz clic en aquí.

Studio te da el poder de crear widgets personalizados y usarlos como herramientas y extensiones. Estos widgets se comportan como ventanas/paneles personalizados en Studio, y puedes acoplarlos dentro de tu interfaz o hacer que floten como ventanas separadas.

Crear interfaces de widgets

Todos los widgets de Studio comienzan como objetos DockWidgetPluginGui que puedes llenar con GuiObjects, como etiquetas de texto y botones. Para crear una GUI de widget vacía, llama a la función CreateDockWidgetPluginGui(), pasando un ID y un objeto DockWidgetPluginGuiInfo.

Ten en cuenta que el constructor DockWidgetPluginGuiInfo.new() espera sus parámetros en un orden específico como sigue:

#PropiedadTipoDescripción
1Enum.InitialDockStateEnumUna de las enumeraciones de Enum.InitialDockState.
2InitialEnabledBooleanoEl estado inicial habilitado (visible) de la GUI del widget.
3InitialEnabledShouldOverrideRestoreBooleanoSi es verdadero, el valor de InitialEnabled anula el estado habilitado guardado previamente.
4FloatingXSizeEnteroEl ancho inicial de la GUI cuando InitialDockState está configurado en Enum.InitialDockState.Float.
5FloatingYSizeEnteroLa altura inicial de la GUI cuando InitialDockState está configurado en Enum.InitialDockState.Float.
6MinWidthEnteroEl ancho mínimo de la GUI, con algunas variaciones específicas de la plataforma.
7MinHeightEnteroLa altura mínima de la GUI, con algunas variaciones específicas de la plataforma.
-- Crear un nuevo objeto "DockWidgetPluginGuiInfo"
local widgetInfo = DockWidgetPluginGuiInfo.new(
Enum.InitialDockState.Float, -- El widget se inicializará en un panel flotante
true, -- El widget estará habilitado inicialmente
false, -- No anular el estado habilitado anterior
200, -- Ancho predeterminado de la ventana flotante
300, -- Altura predeterminada de la ventana flotante
150, -- Ancho mínimo de la ventana flotante
150 -- Altura mínima de la ventana flotante
)
-- Crear nueva GUI de widget
local testWidget = plugin:CreateDockWidgetPluginGui("TestWidget", widgetInfo)
testWidget.Title = "Widget de Prueba" -- Título opcional del widget

Personalizar la interfaz del widget

Una vez que creas un widget, puedes personalizar su interfaz de usuario con GuiObjects como TextLabels informativas o ImageButtons interactivas. Por ejemplo, el siguiente código agrega un TextButton básico a la ventana de la GUI:

-- Crear nueva GUI de widget
local testWidget = plugin:CreateDockWidgetPluginGui("TestWidget", widgetInfo)
testWidget.Title = "Widget de Prueba" -- Título opcional del widget
local testButton = Instance.new("TextButton")
testButton.BorderSizePixel = 0
testButton.TextSize = 20
testButton.TextColor3 = Color3.new(1,0.2,0.4)
testButton.AnchorPoint = Vector2.new(0.5,0.5)
testButton.Size = UDim2.new(1,0,1,0)
testButton.Position = UDim2.new(0.5,0,0.5,0)
testButton.SizeConstraint = Enum.SizeConstraint.RelativeYY
testButton.Text = "Haz clic en mí"
testButton.Parent = testWidget

Cambiar los temas de color de Studio

Los widgets de Studio efectivos idealmente coinciden con la configuración de tema de Studio y se ajustan dinámicamente cuando el tema cambia. Por ejemplo, si un desarrollador está utilizando el tema oscuro, el color de fondo del widget, las imágenes y las etiquetas de texto deberían verse bien junto a los colores nativos del tema de Studio.

La siguiente adición de código utiliza una función syncGuiColors() que se llama inicialmente junto con una tabla de objetos de GUI para sincronizar. Dentro de la función, una función anidada setColors() recorre los objetos y sincroniza aspectos específicos de ellos utilizando GetColor() con enumeraciones Enum.StudioStyleGuideColor. Esta función setColors() se ejecuta inmediatamente para sincronizar el tema de Studio, luego se conecta al evento ThemeChanged para detectar futuros cambios de tema.

testButton.Parent = testWidget
local function syncGuiColors(objects)
local function setColors()
for _, guiObject in objects do
-- Sincronizar color de fondo
guiObject.BackgroundColor3 = settings().Studio.Theme:GetColor(Enum.StudioStyleGuideColor.MainBackground)
-- Sincronizar color de texto
guiObject.TextColor3 = settings().Studio.Theme:GetColor(Enum.StudioStyleGuideColor.MainText)
end
end
-- Ejecutar la función 'setColors()' para sincronizar colores inicialmente
setColors()
-- Conectar el evento 'ThemeChanged' a la función 'setColors()'
settings().Studio.ThemeChanged:Connect(setColors)
end
-- Ejecutar la función 'syncGuiColors()' para sincronizar colores de los objetos proporcionados
syncGuiColors({testButton})

Personalizar los cursores del mouse

Para mejorar la interacción esperada con los elementos del widget, puedes establecer cursores del mouse específicos del sistema para eventos de GUI, como MouseEnter y MouseLeave. El siguiente código demuestra cómo conectar una función a los eventos MouseEnter y MouseLeave de testButton para cambiar el cursor del mouse:

local function setCursor(cursorAsset)
plugin:GetMouse().Icon = cursorAsset
end
testButton.MouseEnter:Connect(function()
setCursor("rbxasset://SystemCursors/PointingHand")
end)
testButton.MouseLeave:Connect(function()
setCursor("")
end)

Consulta la siguiente tabla para obtener una lista de cursores del mouse y sus posibles casos de uso:

Icono del cursor del mouseActivoCaso de uso
rbxasset://SystemCursors/ArrowHacer clic y selección predeterminados.
rbxasset://SystemCursors/PointingHandPasar el mouse sobre un enlace/botón activo.
rbxasset://SystemCursors/OpenHandPasar el mouse sobre un elemento arrastrable.
rbxasset://SystemCursors/ClosedHandArrastrar un elemento.
rbxasset://SystemCursors/IBeamPasar el mouse sobre un campo de texto.
rbxasset://SystemCursors/SizeNSPasar el mouse sobre un controlador de redimensionamiento vertical.
rbxasset://SystemCursors/SizeEWPasar el mouse sobre un controlador de redimensionamiento horizontal.
rbxasset://SystemCursors/SizeNESWPasar el mouse sobre un controlador de redimensionamiento de esquina.
rbxasset://SystemCursors/SizeNWSEPasar el mouse sobre un controlador de redimensionamiento de esquina.
rbxasset://SystemCursors/SizeAllPasar el mouse sobre un controlador de redimensionamiento multidireccional.
rbxasset://SystemCursors/SplitNSPasar el mouse sobre un controlador de "división" vertical.
rbxasset://SystemCursors/SplitEWPasar el mouse sobre un controlador de "división" horizontal.
rbxasset://SystemCursors/ForbiddenPasar el mouse sobre un elemento bloqueado/prohibido.
rbxasset://SystemCursors/WaitIndicar que una acción está en progreso.
rbxasset://SystemCursors/BusyIndicar que el sistema está ocupado.
rbxasset://SystemCursors/CrossPasar el mouse sobre un área de selección precisa.

Recopilar entrada del usuario

Los elementos de la interfaz de usuario como TextBox y TextButton funcionan normalmente en los widgets de Studio, y puedes construir interfaces como lo harías normalmente en Roblox. Sin embargo, UserInputService no funciona ya que estos servicios esperan que la ventana principal del juego esté en foco.

Una solución alternativa para eventos de entrada genéricos es crear un Frame transparente y superponerlo sobre toda la pantalla. El siguiente ejemplo de código crea un marco, y cuando el usuario hace clic en el marco, el evento GuiObject.InputBegan captura la entrada del teclado en el marco hasta que el usuario hace clic fuera:

local frame = Instance.new("Frame")
frame.BackgroundTransparency = 1 -- Ocultar el marco
frame.Size = UDim2.new(1, 0, 1, 0) -- Cubrir la pantalla
frame.Position = UDim2.new(0, 0, 0, 0)
frame.Parent = testWidget
local function onInputBegan(inputObject)
-- Procesar el objeto de entrada aquí, por ejemplo, detectar pulsaciones de teclas
end
frame.InputBegan:Connect(onInputBegan)

Interacción de arrastrar y soltar

Usar interacciones de arrastrar y soltar para tus widgets es una forma sencilla de mejorar el flujo de datos. Para crear esta interacción, debes definir el elemento a arrastrar, iniciar el arrastre, crear un objetivo de caída y procesar la acción de caída.

Crear fuente de arrastre

Puedes iniciar una acción de arrastre llamando a Plugin:StartDrag() cuando el usuario presiona un botón del mouse en algún elemento de la interfaz de usuario, típicamente un TextButton o ImageButton dentro de un widget. El siguiente ejemplo de código crea un widget de ventana único con un botón de texto dentro de él.

-- Crear el widget primero
local widgetInfo = DockWidgetPluginGuiInfo.new(Enum.InitialDockState.Float, true, true, 300, 200)
local dragSourceWidget = plugin:CreateDockWidgetPluginGui("Fuente de Arrastre", widgetInfo)
dragSourceWidget.Title = "Fuente de Arrastre"
-- Crear un TextButton que iniciará el arrastre
local dragButton = Instance.new("TextButton")
dragButton.Size = UDim2.new(1, 0, 1, 0)
dragButton.Text = "¡Arrástrame!"
dragButton.Parent = dragSourceWidget

Iniciar el arrastre

Cuando el usuario hace clic en el TextButton, puedes iniciar el arrastre a través del evento MouseButton1Down() que se activa tan pronto como el usuario presiona el botón del mouse.

Dentro de la función conectada, determina los datos a arrastrar. El tipo de los datos debe reflejarse en la clave MimeType, el contenido del arrastre debe reflejarse dentro de la clave Data, y el remitente debe describirse a sí mismo en la clave Sender. Consulta la página de Plugin:StartDrag() para más detalles.

local function onButton1Down()
local dragInfo = {
Data = "Hola, mundo", -- Los datos que se están arrastrando
MimeType = "text/plain", -- Describe el tipo MIME de los datos
Sender = "SomeDragSource", -- Describe de dónde provienen los datos
MouseIcon = "", -- Contenido de imagen para usar en el cursor
DragIcon = "", -- Contenido de imagen para renderizar bajo el cursor durante el arrastre
HotSpot = Vector2.zero -- Dónde centrar el cursor en el DragIcon
}
plugin:StartDrag(dragInfo)
end
dragButton.MouseButton1Down:Connect(onButton1Down)

Crear objetivo de caída

El evento PluginGui.PluginDragDropped se activa cuando el usuario suelta su mouse en una ventana durante un arrastre. Cuando esto ocurre, necesitas definir un objetivo de caída como un segundo widget con un TextLabel para detectar las caídas.

local dragTargetWidget = plugin:CreateDockWidgetPluginGui("Objetivo de Caída", widgetInfo)
dragTargetWidget.Title = "Objetivo de Caída"
-- Esta TextLabel mostrará lo que se soltó
local textLabel = Instance.new("TextLabel")
textLabel.Size = UDim2.new(1, 0, 1, 0)
textLabel.Text = "Suelta aquí..."
textLabel.Parent = dragTargetWidget

Procesar la acción de caída

Después de crear un objetivo de caída, conecta el evento PluginGui.PluginDragDropped en el widget de objetivo de caída:

local function onDragDrop(dragData)
print("PluginDragDropped")
if dragData.MimeType == "text/plain" then
textLabel.Text = dragData.Data
else
textLabel.Text = dragData.MimeType
end
end
dragTargetWidget.PluginDragDropped:Connect(onDragDrop)

Mientras un arrastre aún está en progreso, estos tres eventos se activan a medida que el usuario mueve su mouse sobre un widget:

  • PluginDragEntered – se activa cuando el usuario pasa el mouse sobre una ventana
  • PluginDragMoved – se activa repetidamente a medida que el usuario mueve su mouse sobre una ventana. Esto es útil para mostrar un mensaje de "¡Suelta aquí!".
  • PluginDragLeft – se activa cuando el cursor del usuario sale de una ventana. Esto es útil para ocultar un mensaje de "¡Suelta aquí!".
©2026 Roblox Corporation. Roblox, el logotipo de Roblox y "Powering Imagination" son algunas de nuestras marcas registradas y no registradas en los Estados Unidos y otros países.