¡Bienvenido a este Codelab sobre cómo agregar interacciones personalizadas en Roblox! Anteriormente, aprendimos a agregar interacciones predefinidas, es decir, aquellas que vienen integradas en la herramienta, como sentarse, puntos de aparición, o eventos básicos. Sin embargo, para enriquecer aún más la experiencia del usuario, podemos crear interacciones personalizadas adaptadas a nuestras necesidades específicas.

Esta será la primera interacción que aprenderemos. Aquí, agregaremos un techo automático para nuestra sala, de modo que al acercarse a cierto punto se abra y al alejarse se cierre. Veamos cómo se puede hacer eso.

  1. El primero será agregar un modelo que tenga la forma del espacio donde vamos a agregar nuestro techo. En este caso sería un techo con forma de semicírculo. Para esto en la caja de herramientas buscaremos directamente un modelo con este nombre y escogeremos este que se muestra a continuación en la imagen.

  1. Una vez agregado el modelo, procederemos a ubicarlo en el espacio que tenemos en el techo y además ajustaremos su tamaño para que se adapte a este.

  1. Ahora procederemos a cambiar el nombre de nuestro componente por "Techo". Recordemos que el nombre lo podemos cambiar editando la propiedad "Name"

  1. Ahora duplicaremos este componente, oprimiendo "CTRL + D" y le cambiaremos el nombre a "Tween2"

  1. Ahora editaremos las propiedades de este nuevo componente (Tween2). En primer lugar, vamos a cambiar su transparencia de 0 a 1. En segundo lugar, desactivaremos la propiedad "CanCollide". En tercer lugar, activaremos la propiedad "Anchored"

  1. Ahora haremos una copia de "Tween2" como aprendimos en anteriores pasos. Además, renombramos este nuevo componente como "Tween1". Este nos servirá como la nueva ubicación que tomará nuestro techo cuando se abra.

  1. Volveremos a duplicar Tween2 y nombraremos este nuevo componente como "Hitbox". Este componente será el que detectará cuando nuestro avatar pase por debajo del techo.

  1. Ahora agruparemos todos los componentes que hemos creado para organizarlos de manera eficiente. Para hacerlo, selecciona todos los componentes en el Explorador. Asegúrate de que todos tengan la propiedad "Anchored" activa: cuando todos los objetos están seleccionados, la casilla de Anchored debe estar marcada en azul. Si no es así, actívala hasta que la casilla se vea azul.

Con todos los componentes seleccionados, presiona CTRL + G para agruparlos. Verás que se crea un nuevo grupo automáticamente. Renombra este grupo a "Techo"

  1. Ahora editaremos la posición de Tween1. Esta posición deberá ser la posición que tomará el techo cuando se abra.

  1. Ahora ajustaremos el tamaño y la ubicación del Hitbox. Este componente será el encargado de detectar la colisión de nuestro avatar, lo cual activará la apertura del techo cuando el avatar se posicione debajo de él.

Para configurar el Hitbox correctamente, sigue estos pasos:

  1. Ahora agregaremos un Script al Hitbox. Para hacer eso daremos click en el símbolo "más" que aparece al lado

Buscaremos el componente Script y lo seleccionaremos

  1. Se nos abrirá un código base como el siguiente:

Borraremos ese código y pegaremos el siguiente:

local doortween1 = script.Parent.Parent.Tween1
local doortween2 = script.Parent.Parent.Tween2
local techo = script.Parent.Parent.Techo
local isTouching = false

function onTouched(hit)
        if not hit or not hit.Parent then return end
        local human = hit.Parent:FindFirstChild("Humanoid")
        if human and human:IsA("Humanoid") and not isTouching then
                isTouching = true
                game.TweenService:Create(techo, TweenInfo.new(0.3, Enum.EasingStyle.Sine, Enum.EasingDirection.In), {CFrame = doortween1.CFrame}):Play()
        end
end

function onTouchEnded(hit)
        if not hit or not hit.Parent then return end
        local human = hit.Parent:FindFirstChild("Humanoid")
        if human and human:IsA("Humanoid") and isTouching then
                isTouching = false
                game.TweenService:Create(techo, TweenInfo.new(0.3, Enum.EasingStyle.Sine, Enum.EasingDirection.In), {CFrame = doortween2.CFrame}):Play()
        end
end

script.Parent.Touched:Connect(onTouched)
script.Parent.TouchEnded:Connect(onTouchEnded)
  return go(f, seed, [])
}

A continuación explicaremos el código:

Este código controla el movimiento de nuestro objeto Techo. La idea es que cuando el avatar del jugador toque el HitBox, Techo se mueva a una posición específica, y cuando el avatar deje de tocarlo, Techo vuelva a su posición original.

Todo esto se maneja con dos eventos de contacto (Touched y TouchEnded) y un sistema de animación suave llamado Tween.

Declaración de Variables:

Función onTouched:

Función onTouchEnded:

Conexión de Eventos:

  1. Una vez copiado el código, oprimiremos CTRL + S para guardar los cambios y ya procederemos a probarlo activando el modo play.

Ahora aprenderemos a agregar y configurar luces automáticas para que cada vez que nuestro avatar cruce por cierta zona se activen, y al dejar de estar en esa zona se apaguen.

Para hacer esto haremos lo siguiente:

  1. Crearemos un objeto que funcione como luz. Para esto, primero insertamos una pieza en nuestra escena:

  1. Cambiaremos el tamaño y ubicación de esta pieza. En este caso la ubicamos en el techo al lado de la imagen del logo de VIVI para iluminar esa parte:

  1. Ahora modificaremos el nombre de esta pieza del explorador. La nombraremos "Luz".

  1. Dentro de las propiedades de este objeto activaremos "Anchored"

  1. Ahora agregaremos un objeto de tipo "PointLight" dentro de nuestro objeto Luz. Para hacer esto daremos clic en el + más al lado del nombre del objeto y buscaremos el que queremos agregar, tal y como hemos aprendido en puntos pasados.

  1. Dentro de las propiedades de nuestro "PointLight" modificaremos la propiedad de "Brightness" y lo dejaremos en 10.

  1. Ahora, al igual que hemos hecho con nuestro techo automático agregaremos un Detector, el cual nos servirá para prender nuestra luz. En este caso nuestro detector será una pieza en forma de Bloque igual a la que usamos para nuestra luz.

Entonces, Insertaremos en nuestra escena una nueva pieza y cambiaremos su nombre a "DetectorLuz":

  1. Ahora cambiaremos el tamaño y la ubicación de nuestro detector. Ubicaremos nuestra pieza justo debajo de nuestra luz, y adecuaremos un tamaño bastante grande para que nuestro avatar pueda colisionar con este. Recordemos que cada vez que nuestro avatar colisione con esta pieza se encenderá la luz.

  1. Ahora cambiaremos algunas propiedades de nuestro detector. Cambiaremos "Transparency" a 1 para que nuestro detector sea transparente.

  1. Desactivaremos la propiedad "CanCollide" y activaremos "Anchored".

  1. Listo, ahora ya tendremos nuestro detector en la escena. Para darle funcionalidad tendremos que insertar un Script, tal como hicimos con el detector del Techo. Entonces agregaremos un Script a DetectorLuz

  1. Cambiaremos el código base que tenemos, por el siguiente:
local detector = script.Parent  -- El detector que detectará el toque
local luzObjeto = detector.Parent:FindFirstChild("Luz")  -- Referencia al objeto "Luz" que contiene el PointLight
local luz

-- Tabla para rastrear los objetos en contacto
local objetosEnContacto = {}

-- Verificamos si encontramos el objeto "Luz" y luego buscamos PointLight en su interior
if luzObjeto then
        luz = luzObjeto:FindFirstChild("PointLight")
end

-- Aseguramos que la luz esté apagada al iniciar
if luz then
        luz.Enabled = false
end

-- Función para cuando algo toca el detector
local function onTouched(hit)
        if hit.Parent:FindFirstChild("Humanoid") then
                -- Añadir el objeto a la tabla de contacto si no está ya registrado
                if not objetosEnContacto[hit] then
                        objetosEnContacto[hit] = true
                end
                -- Encender la luz si es el primer contacto
                luz.Enabled = true
        end
end

-- Función para cuando algo deja de tocar el detector
local function onTouchEnded(hit)
        if hit.Parent:FindFirstChild("Humanoid") then
                -- Eliminar el objeto de la tabla de contacto
                if objetosEnContacto[hit] then
                        objetosEnContacto[hit] = nil
                end
                -- Si no quedan objetos en contacto, apagar la luz
                if next(objetosEnContacto) == nil then
                        luz.Enabled = false
                end
        end
end

-- Conectar los eventos de toque
detector.Touched:Connect(onTouched)
detector.TouchEnded:Connect(onTouchEnded)


A continuación, explicaremos el código que controla el encendido y apagado de la luz cuando el avatar interactúa con el DetectorLuz. Este sistema asegura que la luz reaccione correctamente al contacto del avatar sin parpadeos, usando una tabla para rastrear todos los objetos en contacto.

Declaración de Variables

Función onTouched

Esta función se activa cada vez que un objeto toca el DetectorLuz.

Proceso:

  1. Verifica si el objeto que toca es un avatar buscando un componente Humanoid en su jerarquía.
  2. Si se trata de un avatar, lo agrega a la tabla objetosEnContacto, marcándolo como en contacto.
  3. Enciende la luz (luz.Enabled = true) si no está encendida aún.

Función onTouchEnded

Esta función se activa cuando un objeto deja de tocar el DetectorLuz.

Proceso:

  1. Verifica si el objeto que dejó de tocar es un avatar buscando el componente Humanoid.
  2. Si es un avatar, lo elimina de la tabla objetosEnContacto.
  3. Comprueba si la tabla está vacía (es decir, si no hay más objetos en contacto). Si está vacía, apaga la luz (luz.Enabled = false).}

Resultado:

La luz se apaga solo si no quedan objetos en contacto con el detector.

13. Listo, ahora podremos probar nuestro detector de luz:

Ahora crearemos una imagen dinámica, es decir, una imagen que al momento de acercarse un avatar, cambie por otra. Para hacer esto aprovecharemos el detecto que hemos agregado en el punto anterior y editaremos su Script.

Ahora, el avatar al colisionar no solo editará su imagen, sino en cambio, también cambiará la imagen con el logo de VIVI que tenemos en el fondo.

La imagen que se actualizará puede ser cualquiera de nuestra elección, para subirla lo haremos desde el Gestor de Recursos como hemos aprendido antes.

  1. Ahora es importante cuál va a ser el ID de nuestra imagen original y la que se actualizará, para hacer esto iremos a la Caja de Herramientas e Inventario. Allí seleccionaremos la opción de Mis Adhesivos.

  1. Una vez allí, buscaremos nuestras imágenes y daremos click derecho sobre ellas. Seleccionaremos la opción "ID de la copia del recurso". Esto nos copiará automáticamente el ID de nuestra imagen, deberemos guardarlo en alguna parte, pues lo utilizaremos más tarde. Haremos esto con las dos imágenes

  1. Ahora nos dirigiremos al Script que creamos para el Detector de Luz en el Punto anterior y actualizaremos nuestro código con este nuevo:
local detector = script.Parent  -- El detector que detectará el toque
local luzObjeto = detector.Parent:FindFirstChild("Luz")  -- Referencia al objeto "Luz" que contiene el PointLight
local luz
local decalPart = game.Workspace.Part  -- Referencia a la pieza que contiene el Decal
local decal = decalPart:FindFirstChild("Decal")  -- Referencia al Decal

local objetosEnContacto = {}  -- Tabla para rastrear los objetos en contacto

-- Verificamos si encontramos el objeto "Luz" y luego buscamos PointLight en su interior
if luzObjeto then
        luz = luzObjeto:FindFirstChild("PointLight")
end

-- Aseguramos que la luz esté apagada al iniciar
if luz then
        luz.Enabled = false
end

-- Cambiar imagen del Decal
local originalDecalTexture = "rbxassetid://100000000001"  -- Cambia esto al ID original de la textura
local collisionDecalTexture = "rbxassetid://10000000000"  -- Cambia esto al ID de la textura para la colisión

if decal then
        decal.Texture = originalDecalTexture  -- Configurar el Decal con la textura original al inicio
end

-- Función para cuando algo toca el detector
local function onTouched(hit)
        if hit.Parent:FindFirstChild("Humanoid") then
                -- Añadir el objeto a la tabla de contacto si no está ya registrado
                if not objetosEnContacto[hit] then
                        objetosEnContacto[hit] = true
                end
                -- Encender la luz si es el primer contacto
                luz.Enabled = true

                -- Cambiar la textura del Decal
                if decal then
                        decal.Texture = collisionDecalTexture
                end
        end
end

-- Función para cuando algo deja de tocar el detector
local function onTouchEnded(hit)
        if hit.Parent:FindFirstChild("Humanoid") then
                -- Eliminar el objeto de la tabla de contacto
                if objetosEnContacto[hit] then
                        objetosEnContacto[hit] = nil
                end
                -- Si no quedan objetos en contacto, apagar la luz y restaurar la textura
                if next(objetosEnContacto) == nil then
                        luz.Enabled = false
                        -- Restaurar la textura original del Decal
                        if decal then
                                decal.Texture = originalDecalTexture
                        end
                end
        end
end

-- Conectar los eventos de toque
detector.Touched:Connect(onTouched)
detector.TouchEnded:Connect(onTouchEnded)



  1. En esta sección del código cambiaremos los IDs (números que aparecen al lado de //) por los IDs que guardamos previamente:

local originalDecalTexture = "rbxassetid://100000000001" -- Cambia esto al ID original de la textura

local collisionDecalTexture = "rbxassetid://10000000000" -- Cambia esto al ID de la textura para la colisión

  1. Ahora explicaremos brevemente la actualización de nuestro código:

Nuevas variables:

Cambios en onTouched:

Cuando el avatar toca el DetectorLuz, cambia la textura del Decal a collisionDecalTexture (nueva imagen).

Cambios en onTouchEnded:

Cuando el avatar deja de tocar, restaura la textura del Decal a originalDecalTexture (imagen original).

  1. Listo, una vez hecho esto podremos probar nuestra escena con el código actualizado, veremos que inicialmente nuestra pieza tendrá una imagen, pero al acercarnos cambiará por otra:

¡Felicidades por completar este Codelab! Ahora dominas las bases para agregar interacciones personalizadas en Roblox, desde elementos dinámicos como techos automáticos y luces inteligentes, hasta imágenes interactivas que cambian al paso del avatar. Estas habilidades te permiten llevar tus proyectos al siguiente nivel, añadiendo elementos dinámicos e inmersivos que mejoran la experiencia del usuario.