Un HUD o Pantalla de Visualización es un conjunto de elementos de interfaz de usuario que siempre son visibles o accesibles durante el juego, como las pantallas de puntuación, los medidores de salud y los botones de menú. Incluir un HUD es esencial para la mayoría de los juegos porque muestra información que ayuda a los jugadores a tener éxito en sus objetivos de juego.
Un elemento común del HUD es un medidor de salud con un ícono a la izquierda que se puede adaptar a una barra de temporizador, barra de progreso o similar.

Usando Estación Espacial Peligrosa como punto de partida y Fundamentos de UI - Medidor HUD como referencia terminada, este tutorial demuestra:
- Configuración y uso del Emulador de Dispositivos para probar tu diseño en múltiples pantallas emuladas.
- Uso de StarterGui como contenedor de diseño y almacenamiento.
- Cómo posicionar/redimensionar elementos de UI alrededor de controles integrados de Roblox y muescas/islas de dispositivos, como la muesca de la cámara en teléfonos modernos.
- Cómo reemplazar el medidor de salud de Roblox por defecto con tu propio medidor y conectarlo al nivel de salud del personaje.
- Cómo animar la parte central del medidor de salud y establecer su color entre cinco puntos clave de gradiente de color (rojo, naranja, amarillo, lima, verde).
Habilitar el Emulador de Dispositivos
Roblox es inherentemente multiplataforma, ya que los jugadores pueden descubrir y unirse a juegos en su teléfono o tableta, y luego continuar donde lo dejaron en su PC o consola. Los dispositivos móviles (teléfonos y tabletas) tienen la menor cantidad de espacio en pantalla, por lo que es importante que tus elementos de UI se ajusten a pantallas más pequeñas y que sean claramente visibles para los jugadores.
La mejor manera de probar diseños de UI en diferentes plataformas es el Emulador de Dispositivos de Studio. Esta herramienta proporciona una selección preestablecida de dispositivos y te permite agregar tus propios preajustes personalizados.
Abre la plantilla de Estación Espacial Peligrosa en Studio.
Desde el menú Prueba de Studio, activa el Emulador de Dispositivos.
Desde la barra directamente encima de la ventana principal, selecciona una emulación de teléfono como iPhone X o Samsung Galaxy A51. Luego, establece el tamaño de vista en Ajustar a la Ventana para utilizar el máximo espacio en Studio.

Crear un contenedor de pantalla
Un contenedor ScreenGui contiene objetos de UI (GuiObjects) para mostrar en la pantalla de un jugador (en este tutorial, la totalidad del medidor de salud). Para mostrar un ScreenGui y sus objetos hijos a cada jugador que se une al juego, colócalo dentro del contenedor StarterGui. Cuando un jugador se une y su personaje aparece por primera vez, el ScreenGui y su contenido se clonan en el contenedor PlayerGui para ese jugador, ubicado dentro del contenedor Players.

Para insertar un ScreenGui vacío:
En la ventana Explorador, localiza el contenedor StarterGui.

Pasa el cursor sobre el contenedor, haz clic en el botón ⊕ y inserta un ScreenGui.

Cambia el nombre del nuevo contenedor a HUDContainer para reflejar su propósito.

Utilizar áreas seguras
Los teléfonos modernos aprovechan toda la pantalla, pero típicamente incluyen muescas, recortes y otros elementos que ocupan espacio en la pantalla. Cada juego de Roblox también incluye los controles de la barra superior para acceso rápido al menú principal, chat, tabla de clasificación, y más.

Para asegurar que los jugadores puedan ver y acceder a toda la UI sin obstrucciones, Roblox proporciona la propiedad ScreenInsets que controla los insets del área segura para el contenido de un ScreenGui. Cada objeto de UI que posiciones dentro de un ScreenGui es relativo a los límites de los insets.

Mientras que el valor por defecto de CoreUISafeInsets asegura que todos los objetos de UI permanezcan claros de la UI de Roblox y los recortes del dispositivo, DeviceSafeInsets puede ser una mejor opción para utilizar el espacio limitado en pantalla, como se ilustra a continuación.

En la ventana Explorador, selecciona HUDContainer.

En la ventana de Propiedades, establece la propiedad ScreenInsets a DeviceSafeInsets.

Establecer el relleno de los bordes
Con ScreenInsets configurado a DeviceSafeInsets, el contenido ahora puede extenderse directamente hasta el borde superior físico de la pantalla. Sin embargo, una pequeña cantidad de relleno puede ayudar a alejar el medidor de salud (y otros objetos dentro del contenedor) ligeramente de los bordes de la pantalla para una apariencia más limpia y para evitar que sean recortados.

Una forma de aplicar relleno a un contenedor de UI es a través de la inserción de un modificador UIPadding:
Inserta un modificador UIPadding en HUDContainer.

Con el nuevo objeto UIPadding seleccionado, ingresa un valor de 0, 16 para todos los bordes del contenedor (PaddingBottom, PaddingLeft, PaddingRight, PaddingTop). Esto aplica un relleno de 16 píxeles alrededor del contenedor, independientemente de la resolución de la pantalla.

Construir el medidor de salud
Con el contenedor de pantalla configurado, puedes comenzar a construir el medidor de salud utilizando objetos de UI de Roblox como marcos y una etiqueta de imagen.

Crear el marco padre
Similar a aplicaciones de diseño como Figma y Photoshop, un Frame en Roblox sirve como un contenedor para otros objetos de UI. Para este tutorial, todo el medidor de salud estará contenido en un solo marco padre, lo que facilita su reposicionamiento a través de varios diseños de HUD.
Inserta un Frame en HUDContainer. El nuevo marco aparece en la esquina superior izquierda como un cuadrado blanco vacío.

Cambia el nombre de la nueva instancia de marco a MeterBar.

Posicionar el marco
En Roblox, la posición de un objeto de UI está representada por un conjunto de coordenadas UDim2 que contiene valores Scale y Offset para ambos ejes X y Y:


Para posicionar un objeto de UI en la esquina superior derecha del contenedor de pantalla, Scale es el mejor enfoque porque un valor X de 1 (100%) representa el borde derecho del contenedor, independientemente del tamaño físico en píxeles de la pantalla. De manera similar, un valor de escala Y de 0 (0%) representa el borde superior del contenedor.

Además, necesitarás establecer un punto de anclaje superior derecho para el marco padre para definir su punto de origen. Los valores aceptables están entre 0 y 1, en relación con el tamaño del objeto, por lo que un valor de anclaje de 1, 0 coloca el punto de anclaje del marco en su esquina superior derecha.

En la ventana Explorador, selecciona el marco MeterBar que insertaste anteriormente.

Ingresa 1, 0 para la propiedad AnchorPoint. El marco ahora debería estar posicionado en la esquina superior derecha del área segura del dispositivo, ligeramente indentado del borde como resultado del relleno.

Redimensionar el marco
Al igual que la posición, el Size de un objeto de UI está representado por un conjunto de coordenadas UDim2 que contiene valores Scale y Offset para ambos ejes X y Y.
Por defecto, el tamaño del nuevo marco es {0, 100},{0, 100}, lo que significa 100 píxeles tanto de ancho (X) como de alto (Y). Si bien un valor de píxeles estricto es útil en ciertos casos, muchos elementos de UI escalan de manera más responsiva en múltiples pantallas cuando se establecen como un porcentaje del tamaño total del contenedor de pantalla.
Con el marco MeterBar seleccionado, accede a la ventana de Propiedades y navega a la propiedad Size.
Ingresa un valor de 0.35, 0, 0.05, 0 para establecer un tamaño porcentual de 35% de ancho y 5% de alto sin desplazamientos de píxeles añadidos.

Estilizar el marco
Por defecto, los Frames están llenos de un sólido blanco. El medidor de salud final debe tener un relleno más oscuro y ligeramente opaco, así como un contorno oscuro, para que se destaque mejor en fondos claros y oscuros.

Con el marco MeterBar seleccionado, ingresa 0 para la propiedad BackgroundColor3. Studio lo convertirá automáticamente al valor RGB de [0, 0, 0].
Ingresa 0.75 para la propiedad BackgroundTransparency. En Roblox, la transparencia varía de 0 para completamente opaco a 1 para completamente transparente, por lo que 0.75 equivale al 25% de opacidad en otras aplicaciones como Figma o Photoshop.

Inserta un objeto UIStroke, un potente modificador de UI que añade un trazo personalizable al marco.

Con el nuevo UIStroke seleccionado, establece las siguientes propiedades:
- Thickness = 3
- Transparency = 0.25 (75% opaco)

Para finalizar el estilo del marco del medidor, puedes redondear las esquinas para formar una forma de "pastilla" en lugar de un rectángulo afilado.
Inserta una instancia de UICorner en el marco MeterBar.

Con el nuevo modificador UICorner seleccionado, establece la propiedad CornerRadius a 0.5, 0. Usar un valor de escala de 0.5 (50%) en lugar de un valor en píxeles es especialmente conveniente para la barra del medidor porque asegura una curva completamente redondeada sin importar cuán alta o ancha se vuelva el contenedor.

Crear el relleno interno
Ahora que el marco contenedor del medidor de salud está completo, puedes añadir una porción de relleno interno para representar la salud variable del personaje. Dado que solo necesita ser una región llena sólida, un Frame hijo dentro del marco padre es adecuado.

Inserta un Frame hijo en el marco MeterBar.
Cambia el nombre de la nueva instancia de marco a InnerFill.

Con InnerFill seleccionado, establece las siguientes propiedades:
- AnchorPoint = 0, 0.5 (borde izquierdo y centro vertical)
- Position = 0, 0, 0.5, 0
- Size = 1, 0, 1, 0
Dado que los hijos de los marcos están posicionados y dimensionados en relación con su padre, el uso de escala hace que el marco interno llene el ancho y la altura completos del padre, comenzando desde el borde izquierdo del padre.

Para coincidir con la forma de "pastilla" del marco padre, inserta un UICorner adicional en InnerFill.

Con el nuevo modificador UICorner seleccionado, establece su propiedad CornerRadius a 0.5, 0 para coincidir con la forma de "pastilla" del marco padre MeterBar.

Para representar mejor que un medidor lleno indica buena salud, selecciona InnerFill y establece su propiedad BackgroundColor3 a [0, 225, 50] (en una tarea posterior, programarás este color para cambiar según la salud real).

Añadir el ícono
Para indicar más claramente el propósito del medidor, puedes añadir una etiqueta de imagen al lado izquierdo, en este caso un corazón rojo que comúnmente simboliza salud o vida.

Inserta un ImageLabel en el marco MeterBar. Este objeto te permite aplicar un activo de imagen 2D que ha sido subido como un decal a Roblox.
Cambia el nombre de la nueva etiqueta a Icon.

Con Icon seleccionado, establece su propiedad ZIndex a 2. Mientras que los objetos de UI recién insertados siempre se superponen a los objetos insertados anteriormente, este cambio asegura que el ícono siempre se muestre frente a los elementos del marco del medidor.

Para asegurar que el ImageLabel del ícono siempre mantenga una relación de aspecto de 1:1, inserta un UIAspectRatioConstraint. Aunque esta restricción tiene propiedades personalizables para controlar la relación de aspecto, puedes dejar sus valores predeterminados intactos.

Con Icon seleccionado, finaliza la apariencia y posición cambiando las siguientes propiedades:
- AnchorPoint = 0.5, 0.5 (anclaje central)
- BackgroundTransparency = 1 (100% transparente)
- Position = 0, 0, 0.5, 0 (lado izquierdo del medidor y centro vertical)
- Size = 2, 0, 2, 0 (200% del tamaño total del marco MeterBar, restringido a 1:1 por el UIAspectRatioConstraint)

Restringir el tamaño
Mientras que una altura de escala de 0.05 (5%) se ve bien en pantallas de teléfonos modernos y monitores de juegos que tienen una relación de aspecto de 16:9 o más ancha, el medidor puede verse ligeramente demasiado alto en pantallas de tabletas y teléfonos más antiguos. Puedes comprobar esto emulando una tableta como el iPad 7ª Generación desde el Emulador de Dispositivos.


Para mantener la altura de la barra del medidor más consistente con pantallas más anchas, puedes aplicar un UISizeConstraint para limitar la altura máxima en píxeles.
Inserta un UISizeConstraint en el marco MeterBar.

Con la nueva restricción seleccionada, establece su propiedad MaxSize a inf, 20 para restringir su altura a 20 píxeles mientras se aplica ninguna restricción de ancho.

Ahora, la barra del medidor mantiene una altura más consistente entre pantallas más anchas y más altas.

Reemplazar el medidor de salud por defecto
Los juegos de Roblox incluyen un medidor de salud por defecto que se vuelve visible cuando los personajes reciben daño. Si mantienes visible el medidor por defecto, se duplicará y potencialmente se superpondrá al medidor personalizado.

Desactivar el medidor por defecto
Para desactivar el medidor de salud por defecto, utilizarás un script de cliente (LocalScript) dentro de StarterPlayerScripts que llama a StarterGui:SetCoreGuiEnabled().
En la ventana Explorador, expande el contenedor StarterPlayer y localiza el contenedor StarterPlayerScripts dentro de él.

Inserta un nuevo LocalScript en el contenedor y renómbralo a HideDefaultHealthMeter para describir su propósito. Los scripts dentro de StarterPlayerScripts se ejecutan automáticamente cuando el jugador local se une a un juego, lo que lo convierte en un contenedor ideal para ejecutar un script que oculta permanentemente el medidor por defecto.

Cuando insertas un nuevo script, se abre automáticamente en una nueva pestaña del editor de scripts (si no lo hace, haz doble clic en el script en la ventana Explorador).
Pega el siguiente código dentro del script HideDefaultHealthMeter:
HideDefaultHealthMeterlocal StarterGui = game:GetService("StarterGui")-- Ocultar medidor de salud por defectoStarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Health, false)Explicación del CódigoLínea Propósito 1 Obtiene una referencia a un servicio central, StarterGui, que representa el mismo contenedor donde creaste el medidor de salud personalizado y cuyos contenidos se clonan en el contenedor PlayerGui para cada jugador que se une al juego. 4 Llama al método SetCoreGuiEnabled() del servicio e instruye que el medidor de salud por defecto sea desactivado (false).
Si ahora pruebas el juego y recibes daño, notarás que el medidor por defecto está desactivado y oculto (programarás el medidor personalizado para reflejar cambios de salud en la siguiente sección).

Escuchar cambios de salud
Todos los modelos de personajes por defecto de Roblox contienen una clase Humanoid que proporciona comportamientos y funcionalidades especiales al personaje, como establecer su velocidad de caminar/correr y gestionar su salud. Los cambios en Health en el servidor se replican a cada cliente del jugador y puedes detectar estos cambios para actualizar tanto el tamaño como el color del medidor de salud personalizado.
En la ventana Explorador, localiza el contenedor StarterCharacterScripts dentro de StarterPlayer.

Inserta un nuevo LocalScript en el contenedor y renómbralo a UpdateCustomMeter para describir su propósito. Los scripts dentro de StarterCharacterScripts se ejecutan automáticamente cada vez que el personaje del jugador aparece, lo que lo convierte en un contenedor ideal para ejecutar un script que restablezca completamente el medidor de salud en cada reaparición.

En la ventana del editor para el script UpdateCustomMeter, pega el siguiente código:
UpdateCustomMeterlocal Players = game:GetService("Players")-- Referencia al jugador local, personaje y humanoidelocal player = Players.LocalPlayerlocal character = player.Characterlocal humanoid = character:WaitForChild("Humanoid")-- Referencia al marco interno de la barra del medidorlocal playerGui = player:WaitForChild("PlayerGui")local meterBarInner = playerGui.HUDContainer.MeterBar.InnerFill-- Colores de secuencia de gradiente (rojo, naranja, amarillo, lima, verde)local gradient = {Color3.fromRGB(225, 50, 0),Color3.fromRGB(255, 100, 0),Color3.fromRGB(255, 200, 0),Color3.fromRGB(150, 225, 0),Color3.fromRGB(0, 225, 50)}-- Función para obtener el color en la secuencia de gradiente desde un punto fraccionallocal function getColorFromSequence(fraction: number): Color3-- Cada color en el gradiente define el inicio y/o el final de una secciónlocal numSections = #gradient - 1-- Cada sección representa una porción de 1local sectionSize = 1 / numSections-- Determina en qué sección cae la fracción solicitadalocal sectionStartIndex = 1 + math.clamp(fraction, 0, 1) // sectionSize-- Obtiene los colores al inicio y al final de la secciónlocal sectionColorStart = gradient[sectionStartIndex]local sectionColorEnd = gradient[sectionStartIndex + 1] or sectionColorStart-- Normaliza la fracción para ser un número de 0 a 1 dentro de la secciónlocal fractionOfSection = math.clamp(fraction, 0, 1) % sectionSize / sectionSize-- Interpola entre el inicio y el final basado en la fracción normalizadareturn sectionColorStart:Lerp(sectionColorEnd, fractionOfSection)endlocal function onHealthChanged()-- Calcula la nueva salud como porcentaje del máximolocal healthFraction = math.max(0, humanoid.Health / humanoid.MaxHealth)-- Establece la barra a los nuevos objetivos de tamaño/colormeterBarInner.Size = UDim2.new(healthFraction, 0, 1, 0)meterBarInner.BackgroundColor3 = getColorFromSequence(healthFraction)end-- Escucha cambios en la salud del humanoidehumanoid.HealthChanged:Connect(onHealthChanged)-- Inicialmente establece (o restablece) el tamaño/color de la barra a la salud actualonHealthChanged()Explicación del CódigoLíneas Propósito 4‑6 Obtiene referencias al Player local, su modelo Character, y la clase Humanoid dentro de él. 9‑10 Obtiene una referencia al objeto InnerFill del medidor que debe ser redimensionado y recoloreado a medida que cambia la salud del personaje. 13‑19 Declara un arreglo de cinco colores (rojo, naranja, amarillo, lima, verde) para recolorear el medidor en varios puntos; por ejemplo, verde para 100% de salud, amarillo para 50%, rojo para 0%, o una mezcla en cualquier fracción entre los puntos clave. 22‑41 Función auxiliar que devuelve la mezcla de color entre cualquiera de los puntos clave de color del gradiente. 43‑50 Función que maneja cualquier cambio en la salud. Aquí, calcula la nueva salud como un porcentaje del MaxHealth del personaje, redimensiona InnerFill a ese porcentaje de escala, y lo recolorea al color devuelto por la función getColorFromSequence(). 53 La conexión principal de evento que detecta cambios en Health replicados desde el servidor y llama a la función onHealthChanged(). 56 Inicialmente (al aparecer o reaparecer el personaje) llama a la función onHealthChanged() para dimensionar y colorear InnerFill al porcentaje correcto. Típicamente esto será el ancho completo y verde.
Si ahora pruebas el juego, notarás que el medidor personalizado actualiza correctamente tanto el tamaño como el color a medida que el personaje recibe daño:
Animar la barra del medidor
Para añadir un nivel extra de pulido al medidor personalizado, puedes animar los cambios de salud a través de tweening, cambiando gradualmente el tamaño y el color de la barra del medidor durante ½ segundo.
Accede a la pestaña del editor de scripts para el script UpdateCustomMeter que editaste anteriormente.
Selecciona todas las líneas (CtrlA o ⌘A) y luego pégalas sobre ellas (CtrlV o ⌘V) con el siguiente código:
UpdateCustomMeterlocal Players = game:GetService("Players")local TweenService = game:GetService("TweenService")-- Referencia al jugador local, personaje y humanoidelocal player = Players.LocalPlayerlocal character = player.Characterlocal humanoid = character:WaitForChild("Humanoid")-- Propiedades de tweenlocal tweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out)-- Referencia al marco interno de la barra del medidorlocal playerGui = player:WaitForChild("PlayerGui")local meterBarInner = playerGui.HUDContainer.MeterBar.InnerFill-- Colores de secuencia de gradiente (rojo, naranja, amarillo, lima, verde)local gradient = {Color3.fromRGB(225, 50, 0),Color3.fromRGB(255, 100, 0),Color3.fromRGB(255, 200, 0),Color3.fromRGB(150, 225, 0),Color3.fromRGB(0, 225, 50)}-- Función para obtener el color en la secuencia de gradiente desde un punto fraccionallocal function getColorFromSequence(fraction: number): Color3-- Cada color en el gradiente define el inicio y/o el final de una secciónlocal numSections = #gradient - 1-- Cada sección representa una porción de 1local sectionSize = 1 / numSections-- Determina en qué sección cae la fracción solicitadalocal sectionStartIndex = 1 + math.clamp(fraction, 0, 1) // sectionSize-- Obtiene los colores al inicio y al final de la secciónlocal sectionColorStart = gradient[sectionStartIndex]local sectionColorEnd = gradient[sectionStartIndex + 1] or sectionColorStart-- Normaliza la fracción para ser un número de 0 a 1 dentro de la secciónlocal fractionOfSection = math.clamp(fraction, 0, 1) % sectionSize / sectionSize-- Interpola entre el inicio y el final basado en la fracción normalizadareturn sectionColorStart:Lerp(sectionColorEnd, fractionOfSection)endlocal function onHealthChanged()-- Calcula la nueva salud como porcentaje del máximolocal healthFraction = math.max(0, humanoid.Health / humanoid.MaxHealth)-- Tween la barra a nuevos objetivos de tamaño/colorlocal tweenGoal = {Size = UDim2.new(healthFraction, 0, 1, 0),BackgroundColor3 = getColorFromSequence(healthFraction)}local meterBarTween = TweenService:Create(meterBarInner, tweenInfo, tweenGoal)meterBarTween:Play()end-- Escucha cambios en la salud del humanoidehumanoid.HealthChanged:Connect(onHealthChanged)-- Inicialmente establece (o restablece) el tamaño/color de la barra a la salud actualonHealthChanged()Adiciones/Cambios ClaveLíneas Propósito 2 Obtiene una referencia a TweenService para implementar la funcionalidad de tweening dentro del script. 10 Crea un constructor TweenInfo que define la duración del tween previsto, el estilo de easing, y la dirección de easing. 52‑57 En lugar de simplemente establecer el tamaño y el color de la barra como en la versión anterior, declara una tabla tweenGoal con el tamaño/color objetivo, crea un nuevo tween usando los parámetros tweenInfo y tweenGoal, y reproduce el nuevo tween.
Si ahora pruebas el juego, notarás que el medidor personalizado hace tween entre cada cambio de salud:
Añadir un efecto de daño
El sistema de medidor de salud por defecto incluye un breve y sutil tinte rojo en los bordes de la pantalla cuando el personaje recibe daño. Al desactivar el medidor por defecto, este efecto se elimina, pero puedes reemplazarlo con tu propia implementación.
Accede a la pestaña del editor de scripts para el script UpdateCustomMeter que editaste anteriormente.
Selecciona todas las líneas y pégalas sobre ellas con el siguiente código:
UpdateCustomMeterlocal Workspace = game:GetService("Workspace")local Players = game:GetService("Players")local TweenService = game:GetService("TweenService")-- Referencia al jugador local, personaje y humanoidelocal player = Players.LocalPlayerlocal character = player.Characterlocal humanoid = character:WaitForChild("Humanoid")-- Propiedades de tweenlocal tweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out)-- Variable para almacenar/cachear la salud del personajelocal cachedHealth = humanoid.Health / humanoid.MaxHealth-- Obtener (o crear nuevo) efecto de corrección de color dentro de la cámara del jugadorlocal colorCorrection = Workspace.CurrentCamera:FindFirstChildWhichIsA("ColorCorrectionEffect") or Instance.new("ColorCorrectionEffect", Workspace.CurrentCamera)colorCorrection.Name = "DamageColorEffect"-- Referencia al marco interno de la barra del medidorlocal playerGui = player:WaitForChild("PlayerGui")local meterBarInner = playerGui.HUDContainer.MeterBar.InnerFill-- Colores de secuencia de gradiente (rojo, naranja, amarillo, lima, verde)local gradient = {Color3.fromRGB(225, 50, 0),Color3.fromRGB(255, 100, 0),Color3.fromRGB(255, 200, 0),Color3.fromRGB(150, 225, 0),Color3.fromRGB(0, 225, 50)}-- Función para obtener el color en la secuencia de gradiente desde un punto fraccionallocal function getColorFromSequence(fraction: number): Color3-- Cada color en el gradiente define el inicio y/o el final de una secciónlocal numSections = #gradient - 1-- Cada sección representa una porción de 1local sectionSize = 1 / numSections-- Determina en qué sección cae la fracción solicitadalocal sectionStartIndex = 1 + math.clamp(fraction, 0, 1) // sectionSize-- Obtiene los colores al inicio y al final de la secciónlocal sectionColorStart = gradient[sectionStartIndex]local sectionColorEnd = gradient[sectionStartIndex + 1] or sectionColorStart-- Normaliza la fracción para ser un número de 0 a 1 dentro de la secciónlocal fractionOfSection = math.clamp(fraction, 0, 1) % sectionSize / sectionSize-- Interpola entre el inicio y el final basado en la fracción normalizadareturn sectionColorStart:Lerp(sectionColorEnd, fractionOfSection)endlocal function onHealthChanged()-- Calcula la nueva salud como porcentaje del máximolocal healthFraction = math.max(0, humanoid.Health / humanoid.MaxHealth)-- Tween la barra a nuevos objetivos de tamaño/colorlocal tweenGoal = {Size = UDim2.new(healthFraction, 0, 1, 0),BackgroundColor3 = getColorFromSequence(healthFraction)}local meterBarTween = TweenService:Create(meterBarInner, tweenInfo, tweenGoal)meterBarTween:Play()-- Mostrar efecto de daño si la nueva salud es menor que la salud cacheadaif healthFraction < cachedHealth then-- Cachear el nuevo valor de saludcachedHealth = healthFraction-- Establecer la corrección de color a rojo como el tinte inicial antes de hacer tweencolorCorrection.TintColor = Color3.fromRGB(255, 25, 25)colorCorrection.Saturation = 2.5-- Tween el tinte de vuelta a blanco (neutral y sin cambio de tinte de lo normal)local colorCorrectionTweenGoal = {TintColor = Color3.fromRGB(255, 255, 255),Saturation = 0}local colorCorrectionTween = TweenService:Create(colorCorrection, tweenInfo, colorCorrectionTweenGoal)colorCorrectionTween:Play()endend-- Escucha cambios en la salud del humanoidehumanoid.HealthChanged:Connect(onHealthChanged)-- Inicialmente establece (o restablece) el tamaño/color de la barra a la salud actualonHealthChanged()Adiciones/Cambios ClaveLíneas Propósito 14 Establece una referencia de marcador de posición (cachedHealth) para rastrear la cantidad de salud del personaje entre cambios, para que puedas comparar si un cambio es menor (daño). 17‑18 En la aparición inicial del personaje, crea un nuevo ColorCorrectionEffect dentro de la Camera actual del jugador, o obtiene una referencia a la misma instancia en reaparecimientos posteriores. Al parentear este efecto de post-procesamiento a la cámara del jugador, solo se aplica a su pantalla local, no a la pantalla de cada jugador en el servidor. 68‑83 Primero realiza una verificación condicional para confirmar que el cambio de salud es menor que el valor de cachedHealth, indicando daño; si es así, establece cachedHealth al nuevo valor. Luego, establece el tinte del ColorCorrectionEffect a [255, 25, 25] (rojo) con mayor saturación, y luego hace tween del tinte de vuelta al valor predeterminado de blanco neutro ([255, 255, 255]) sin saturación.
Si ahora pruebas el juego, notarás que la pantalla parpadea brevemente en rojo cada vez que el personaje recibe daño:
