Desarrollo / ROBLOX
Puntos de control en Roblox Studio: un obby de práctica separado
Crea dos puntos de control, asigna el lugar de reaparición por jugador y comprueba muerte, repetición, orden y salida de la sesión.
Define primero la mecánica pequeña #
Construye un recorrido corto con Start, Checkpoint1 y Checkpoint2. El jugador los alcanza en orden. Tras aceptar el contacto con el siguiente punto, morir debe devolverlo allí. Volver a una plataforma anterior no reduce progreso. Un segundo jugador tiene estado y destino de reaparición independientes. Esta regla permite comparar el resultado esperado con el observado.
Es un prototipo nuevo de aprendizaje, no una implementación de Stone Trail ni de otro juego del autor del sitio. El código se escribió para esta lección y su lógica se revisa aquí, pero no se ha ejecutado en el motor Roblox para este artículo. El progreso vive solo en la memoria del servidor actual. No añadimos guardado entre visitas, premios ni defensa contra todas las formas de saltarse el recorrido. Verifica primero esta mecánica limitada.
1. Prepara otra escena con nombres exactos #
Guarda un proyecto pequeño nuevo para no interferir con un juego en funcionamiento. Workspace necesita un SpawnLocation llamado Start y un Folder llamado Checkpoints. Dentro crea dos SpawnLocations: Checkpoint1 y Checkpoint2. Añade un Script normal llamado CheckpointServer en ServerScriptService. Las rutas finales son Workspace.Start, Workspace.Checkpoints.Checkpoint1, Workspace.Checkpoints.Checkpoint2 y ServerScriptService.CheckpointServer. Checkpoint 1 con un espacio es otro nombre; respeta la escritura.
El resto de plataformas puede ser Part normales ancladas. Los puntos deben ser realmente SpawnLocation, no Part de aspecto parecido. Quita spawns adicionales ajenos a esta escena nueva de ejercicio. No necesitas un conjunto de scripts desconocidos incluidos en un modelo: tus plataformas y un archivo servidor bastan. Antes de programar comprueba que se ven los tres puntos y no se superponen. Así será más fácil relacionar contacto y resultado.
2. Prepara contacto y espacio de aparición #
Coloca Start, después Checkpoint1 y finalmente Checkpoint2 en un camino corto seguro. Sepáralos para tocar cada uno por separado. Deja espacio libre sobre los SpawnLocation: el personaje no debe aparecer dentro de una pared, bajo un techo bajo ni al borde de una caída. Color y etiqueta distinguen las plataformas, pero no asignan progreso. Las trampas complicadas no son necesarias para esta primera comprobación.
La tabla siguiente fija la configuración del ejercicio y el script repite los valores al iniciar. Los puntos permiten aparecer sin depender del equipo; se desactiva cambiar de equipo al tocar. CanTouch permite eventos de contacto y Anchored mantiene la plataforma quieta. Si después introduces equipos o collision groups, vuelve a comprobar permisos y contacto físico. Por ahora conserva la carga automática normal de personajes; un sistema de carga personalizado no forma parte de este prototipo.
| Propiedad | Valor | Uso en este ejercicio |
|---|---|---|
| Class | SpawnLocation | Plataformas de aparición |
| Anchored | true | Plataformas fijas |
| CanCollide | true | El personaje puede pisarlas |
| CanTouch | true | Permite detectar contacto físico |
| Enabled | true | Punto disponible |
| Neutral | true | Sin restricción por equipo |
| AllowTeamChangeOnTouch | false | Tocar no cambia equipo |
3. Coloca el script completo en el servidor #
Abre CheckpointServer en ServerScriptService y sustituye su contenido por todo el ejemplo inferior. Copia preparación e inicialización además del controlador Touched. La tabla checkpoints establece un orden fijo, sin depender del orden de GetChildren. configure comprueba las clases y configura propiedades. WaitForChild espera nombres ausentes; assert informa de una clase incorrecta. Repara la jerarquía antes de probar el recorrido.
El servidor asigna Player.RespawnLocation y mantiene progress con un Player como clave. Un LocalScript en StarterPlayerScripts no sustituye esta ubicación. Evita otro script que cambie RespawnLocation durante la prueba. Inicia una sesión nueva después de preparar la escena. Insertar el ejemplo en una prueba ya empezada no mueve inmediatamente al personaje vivo a Start: asigna un destino para reaparecer, no ejecuta un teletransporte.
local Players = game:GetService("Players")
local start = workspace:WaitForChild("Start")
local folder = workspace:WaitForChild("Checkpoints")
local checkpoints = {
folder:WaitForChild("Checkpoint1"),
folder:WaitForChild("Checkpoint2"),
}
local progress = {}
local function configure(spawn)
assert(spawn:IsA("SpawnLocation"), "Expected SpawnLocation")
spawn.Anchored = true
spawn.CanCollide = true
spawn.CanTouch = true
spawn.Enabled = true
spawn.Neutral = true
spawn.AllowTeamChangeOnTouch = false
end
configure(start)
for _, checkpoint in ipairs(checkpoints) do
configure(checkpoint)
end
local function initialize(player)
if progress[player] ~= nil then return end
progress[player] = 0
player.RespawnLocation = start
end
Players.PlayerAdded:Connect(initialize)
Players.PlayerRemoving:Connect(function(player)
progress[player] = nil
end)
for _, player in ipairs(Players:GetPlayers()) do
initialize(player)
end
for index, checkpoint in ipairs(checkpoints) do
checkpoint.Touched:Connect(function(hit)
local character = hit:FindFirstAncestorOfClass("Model")
if not character then return end
local player = Players:GetPlayerFromCharacter(character)
if not player or player.Character ~= character then return end
local humanoid = character:FindFirstChildOfClass("Humanoid")
if not humanoid or humanoid.Health <= 0 then return end
local current = progress[player]
if current == nil or index ~= current + 1 then return end
player.RespawnLocation = checkpoint
progress[player] = index
end)
end4. Identifica al jugador detrás de la pieza #
Touched entrega la otra pieza, que puede pertenecer a un personaje, un cubo que cae o un objeto. El controlador busca el Model más próximo, consulta GetPlayerFromCharacter, compara player.Character y comprueba un Humanoid con Health positivo. Sin estas condiciones, un objeto o personaje muerto podría cambiar progreso por error. Un contacto inválido termina con return antes de asignar un destino.
El ejemplo presupone un personaje habitual con Humanoid dentro de su Model. Un rig anidado personalizado exige adaptar deliberadamente la búsqueda; no elimines la comprobación del jugador para ocultar un problema. Un toque observado por el servidor no prueba que se haya completado honestamente la ruta. Movimiento y física requieren un análisis de seguridad aparte. Aquí comprobamos puntos personales en un camino de aprendizaje normal, no un sistema anti-trampas completo.
5. Mantén el orden sin bloquear a todos #
El nuevo jugador empieza con progress 0. Solo se acepta current + 1: primero índice 1 y luego 2. Tras confirmar el primero, nuevos contactos de un pie u otra parte del cuerpo ya no corresponden al próximo índice. Después del segundo también se rechaza volver al primero. La regla impide retroceder y saltarse Checkpoint1. Es nuestra elección didáctica; un recorrido libre necesitaría otro contrato.
No hay un debounce compartido que bloquee a todos tras un toque. Cada Player tiene su propia clave. La comprobación y las dos asignaciones no contienen task.wait ni otra espera. Los jugadores avanzan independientemente. Esto es revisión lógica del controlador breve, no garantía para futuras versiones asíncronas. Si añades premios, consultas de datos o pausas, revisa otra vez llamadas repetidas y el momento de modificar estado.
6. Distingue muerte, reinicio y nueva entrada #
El contacto aceptado cambia RespawnLocation de ese Player. El personaje vivo se queda donde estaba; comprueba el destino durante la siguiente reaparición normal. La muerte crea otro Model de personaje, pero el Player sigue en la sesión y conserva su entrada progress. No reinicies progress en CharacterAdded: borrarías el punto alcanzado en cada muerte.
PlayerRemoving elimina la entrada al salir. Volver a entrar inicializa 0 y Start. Detener una prueba de Studio e iniciar otra también crea sesión nueva. El ejemplo no incluye un botón de reinicio total dentro del juego. Si lo añades, debe reiniciar índice y RespawnLocation; cambiar el texto de una etiqueta no basta. Guardar el proyecto guarda escena y código, no la memoria de la tabla de jugadores.
7. Realiza la secuencia de prueba individual #
Elige Test en el desplegable de pruebas de Studio e inicia. Este modo inserta un personaje; Run simula sin avatar y no sirve para la primera prueba andando. Empieza una sesión nueva y confirma aparición en Start. Camina a Checkpoint1, párate encima y provoca una muerte en un área de caída diseñada aparte para el prototipo. Espera la reaparición normal y anota dónde sucede.
Repite en Checkpoint2. Luego regresa físicamente al primero y comprueba otra muerte: debe conservarse el segundo. No confundas esta prueba con Stop y un Test nuevo, que borran memoria deliberadamente. Registra observación y predicción por separado. Si el área de caída no mata al personaje, todavía no es una prueba fallida de RespawnLocation. Primero confirma que realmente hubo muerte y apareció un personaje nuevo.
8. Prueba objeto, salto de orden y contacto repetido #
En otro intento toca Checkpoint2 antes de Checkpoint1: debe mantenerse Start por la regla de orden. Después completa ambos normalmente. Para comprobar un objeto crea un cubo normal no anclado y deja que caiga físicamente sobre el punto. No corresponde a Player, así que no debe modificar progreso de nadie. Compara el estado servidor o la posterior reaparición del jugador correcto, no el color de la plataforma.
Touched depende de movimiento físico. Cambiar CFrame para superponer dos piezas ancladas no es la misma prueba del evento. Si no hay contacto, revisa CanTouch de ambas piezas y collision groups. No publiques un resultado inventado «cubo rechazado» sin realizar el experimento. La tabla posterior contiene resultados esperados, no un informe de ejecución del ejemplo en Roblox. Conserva esta distinción también en tus propias notas.
9. Comprueba dos progresos independientes #
Selecciona Server & Clients con dos clientes e inicia con Play o F7. A llega al primer punto mientras B permanece en Start. Al morir, A debe reaparecer en Checkpoint1 y B en Start. Luego B alcanza el primero y A el segundo; compara ambos resultados. Prueba también contactos casi simultáneos de los dos personajes con Checkpoint1: un bloqueo compartido no debe dejar sin progreso a uno.
Ver una misma plataforma coloreada en dos cámaras no demuestra la asignación personal. El color de Workspace es compartido; RespawnLocation pertenece a un Player. Anota qué cliente hizo la acción y qué personaje reapareció. Al terminar usa End Session para cerrar toda la sesión multicliente. Dos clientes locales verifican casos concretos; no demuestran rendimiento de un servidor grande ni soporte de avatares anidados o todas las secuencias inusuales.
10. Investiga una condición fallida cada vez #
Si falla un punto, comprueba en orden: ruta exacta, clase SpawnLocation, Script servidor normal, CanTouch, Player vivo, índice esperado y permiso para aparecer. Un nombre mal escrito y el rechazo intencionado del índice 2 tienen causas diferentes. Para errores de ejecución usa la guía de Output enlazada; no repetimos todo el tutorial de consola. La tabla no contiene marcas de aprobado: añade tus observaciones a las expectativas.
Comprueba especialmente que Enabled no se haya desactivado ni Neutral cambiado tras iniciar. El punto debe seguir en Workspace y ser válido para el jugador. Otro script puede modificar propiedades o RespawnLocation después. Si el destino es incorrecto, informa de secuencia y plataforma real, no solo «roto». Verifica una corrección en un intento claro. Añadir esperas interminables no repara una condición de orden incorrecta.
| Caso | Estado esperado | Comprobación |
|---|---|---|
| Test nuevo / entrada | 0; Start | Primera aparición real |
| Checkpoint1 y muerte | 1; Checkpoint1 | Esperar personaje nuevo |
| Checkpoint1 repetido | Sin cambios | Distintas partes del cuerpo |
| Checkpoint2 tras primero | 2; Checkpoint2 | Muerte vuelve al segundo |
| Primero tras segundo | 2; Checkpoint2 | No retrocede |
| Segundo antes del primero | 0; Start | Rechaza saltarse el orden |
| Cubo / Model no jugador | Sin cambios | Sin Player correspondiente |
| Personaje muerto / anterior | Sin cambios | Health y Character actual |
| A avanzó, B no | Destinos A/B independientes | Comprobar ambos tras muerte |
| Salir / Stop y otro test | Estado nuevo 0 | No hay guardado permanente |
11. Guarda el resultado y elige una extensión #
Finaliza la prueba y guarda el prototipo con nombre reconocible. Anota jerarquía, versión del script, carga automática asumida, casos individuales y multicliente realizados y destinos esperados y reales. La revisión lógica del artículo no significa que tu proyecto haya superado pruebas de Studio. Compara los casos importantes en tu escena antes de transferir la mecánica a un juego en funcionamiento.
Un mensaje personal de confirmación o un botón explícito de reinicio puede ser la próxima ampliación pequeña. Guardado permanente es otra tarea: carga, fallos de escritura, versiones de datos y reglas de borrado. Aquí no usamos DataStore. No prometas progreso para siempre. Conserva primero el contrato claro: morir vuelve al punto alcanzado durante la visita y salir termina este progreso de práctica en memoria. Una regla pequeña comprobada se amplía con más claridad.
Fuentes originales
Roblox Creator HubRoblox Creator Hub — Player.RespawnLocation
Roblox Creator Hub — BasePart.Touched and CanTouch
Roblox Creator Hub — Studio testing modes
Roblox Creator Hub — Players lifecycle
Roblox Creator Hub — ServerScriptService