Una puerta que se abre sola cuando llegas es de esas cosas que hacen que un mapa deje de parecer una maqueta. Y es el ejemplo perfecto para entender el ProximityPrompt, que es la herramienta que vas a usar para casi cualquier cosa con la que el jugador interactúe: cofres, botones, palancas, vendedores.
En la demo de abajo puedes mover al jugador y ver cuándo aparece el aviso y cuándo desaparece, cambiando la distancia.
Respuesta rápida
Mete un ProximityPrompt dentro de la puerta, ajústale MaxActivationDistance y conecta su evento Triggered. Cuando el jugador se acerca aparece solo el «Pulsa E»; cuando se aleja, desaparece. No tienes que programar la detección: la hace Roblox.
Lo que necesitas antes de empezar
- Un Part que haga de puerta, Anchored marcado.
- Un
Scriptnormal dentro de él. - Unos 20 minutos.
Las dos formas, y cuál elegir
| Se abre sola al acercarte | Se abre al pulsar E | |
|---|---|---|
| Cómo se hace | Zona con Touched | ProximityPrompt |
| El jugador controla cuándo | No | Sí |
| Se abre sin querer al pasar | Sí, constantemente | No |
| Recomendada para | Puertas automáticas de pasillo | Todo lo demás |
Salvo que quieras específicamente una puerta de supermercado, usa ProximityPrompt. Se abre cuando el jugador quiere, se ve el aviso en pantalla y funciona igual en móvil y con mando sin que hagas nada.
Paso 1: mete el ProximityPrompt
Clic derecho sobre la puerta en el Explorer → Insert Object → ProximityPrompt.
Selecciónalo y mira sus propiedades. Estas cinco son las que importan:
| Propiedad | Qué hace | Valor recomendado |
|---|---|---|
| ActionText | El texto grande. «Abrir», «Coger», «Hablar» | Un verbo, corto |
| ObjectText | El texto pequeño de debajo | El nombre de la cosa |
| MaxActivationDistance | A cuántos studs aparece | 8-10 para una puerta |
| HoldDuration | Segundos que hay que mantener pulsado | 0 en puertas, 1-2 en cosas importantes |
| RequiresLineOfSight | Si tiene que verse el objeto | Desactívalo casi siempre |
Ese último da muchos problemas: si está activado y la puerta es gruesa o hay una columna delante, el aviso no aparece y no entiendes por qué. Desactívalo salvo que lo necesites de verdad.
HoldDuration merece un momento. Ponerlo a 1 o 2 segundos en acciones importantes —vender algo, borrar tu progreso, salir de una zona— evita muchísimos toques accidentales. En una puerta déjalo a 0.

Paso 2: abrirla
-- Script DENTRO del Part de la puerta
local TweenService = game:GetService("TweenService")
local puerta = script.Parent
local prompt = puerta:WaitForChild("ProximityPrompt")
local cerrada = puerta.CFrame
local abierta = cerrada * CFrame.Angles(0, math.rad(90), 0)
local estaAbierta = false
local moviendose = false
prompt.Triggered:Connect(function(jugador)
if moviendose then return end -- no dejamos interrumpir a media animación
moviendose = true
local destino = estaAbierta and cerrada or abierta
local tween = TweenService:Create(
puerta,
TweenInfo.new(0.6, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
{CFrame = destino}
)
tween:Play()
tween.Completed:Wait()
estaAbierta = not estaAbierta
prompt.ActionText = estaAbierta and "Cerrar" or "Abrir"
moviendose = false
end)
Fíjate en tres cosas:
Triggeredte da el jugador como parámetro. Lo puedes usar para comprobar si tiene la llave, si es de un equipo, lo que sea.- El bloqueo
moviendoseimpide que alguien la abra y cierre a lo loco dejando la puerta girada a medias. - El texto cambia según el estado. Es un detalle de dos líneas que se nota mucho.
Paso 3: el giro no es sobre la bisagra
Si has probado el código de arriba, habrás visto que la puerta gira sobre su centro, no sobre el borde. Parece que flota.
Esto es lo que confunde a todo el mundo. CFrame.Angles gira sobre el punto de origen del Part, que está en su centro. Para girar sobre la bisagra hay que desplazar, girar y volver:
-- La bisagra está en el borde izquierdo de la puerta
local anchura = puerta.Size.X
local aBisagra = CFrame.new(-anchura / 2, 0, 0)
local cerrada = puerta.CFrame
local abierta = cerrada * aBisagra * CFrame.Angles(0, math.rad(90), 0) * aBisagra:Inverse()
Léelo de izquierda a derecha: muévete a la bisagra, gira allí, y vuelve. Ese :Inverse() del final es lo que deshace el desplazamiento.
Si la bisagra está en el otro lado, quítale el menos: CFrame.new(anchura / 2, 0, 0).

Paso 4: puerta con llave
Como Triggered te da el jugador, comprobar cosas es directo:
prompt.Triggered:Connect(function(jugador)
local mochila = jugador:FindFirstChild("Backpack")
local tieneLlave = mochila and mochila:FindFirstChild("LlaveDorada")
if not tieneLlave then
prompt.ActionText = "Necesitas la llave dorada"
task.wait(2)
prompt.ActionText = "Abrir"
return
end
-- aquí el código de abrir
end)
Pruébalo aquí
Acércate a la puerta
Mueve al jugador con el ratón o las flechas. El aviso aparece solo cuando entras en el radio.
Errores habituales
El aviso no aparece nunca
Por orden: que el ProximityPrompt esté dentro de un Part (no de un Model suelto ni de una carpeta), que Enabled esté marcado, y que RequiresLineOfSight esté desactivado.
La puerta gira flotando por el aire
Es lo del paso 3: estás girando sobre el centro. Necesitas el desplazamiento a la bisagra.
La puerta se queda a medias
Alguien la activó mientras se movía. El bloqueo moviendose lo evita.
Se abre para un jugador y para los demás no
El script es un LocalScript. Las puertas van en el servidor: tiene que verlo todo el mundo.
El aviso aparece atravesando la pared
Ahí sí quieres RequiresLineOfSight activado, o bajar MaxActivationDistance.
Preguntas frecuentes
¿Puedo cambiar la tecla?
Sí, con KeyboardKeyCode. Pero E es lo que todo el mundo espera en Roblox: cámbialo solo si tienes un motivo.
¿Funciona en móvil?
Sí, sale un botón táctil automáticamente, y con mando un botón del pad. Es la principal ventaja frente a montártelo a mano.
¿Se puede quitar el aviso de Roblox y poner uno mío?
Sí: pon Style en Custom y dibujas tu propia interfaz escuchando PromptShown y PromptHidden. Es bastante más trabajo.
¿Y para una puerta doble?
Dos Parts, un solo ProximityPrompt, y en Triggered lanzas dos tweens a la vez —cada hoja hacia su lado— sin esperar al primero.
Última revisión: 1 de septiembre de 2026



Deja una respuesta