Implementar el comportamiento del blaster

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

Implementar el comportamiento del blaster es el proceso de programar una mecánica de explosión en experiencias de juegos de disparo en primera persona. Mientras que los jugadores pueden disparar con un solo clic o pulsando un botón, crear un comportamiento de explosión satisfactorio y preciso es importante porque mejora el disfrute de los jugadores del juego en general.

Usando la experiencia de láser tag de ejemplo como referencia, esta sección del tutorial te enseña sobre los scripts detrás de la implementación del comportamiento de los blasters para dos tipos diferentes de blasters, incluyendo orientación sobre:

  • Detectar cuándo los jugadores presionan el botón de explosión.
  • Comprobar si el jugador puede usar su blaster si recientemente presionó el botón de explosión.
  • Generar datos de explosión que le dicen al servidor quién inició la explosión, de dónde provino y cuál fue el destino final de cada rayo láser.
  • Notificar al servidor de los datos de explosión para que pueda realizar las acciones apropiadas si la explosión colisionó con otro jugador.
  • Restablecer el blaster entre cada explosión para darle tiempo suficiente al blaster para enfriarse antes de que pueda explosionar nuevamente.

Después de completar esta sección, aprenderás sobre los scripts que permiten al blaster detectar cuando sus explosiones colisionan con otros jugadores, y luego deducir la cantidad correspondiente de salud según cada tipo de blaster.

Detectar la entrada del jugador

El primer paso para implementar el comportamiento del blaster es escuchar cuándo un jugador presiona el botón de explosión. El tipo de entrada que los jugadores utilizan para presionar el botón de explosión depende del dispositivo que están utilizando para acceder a la experiencia. Por ejemplo, la experiencia de láser tag de muestra admite controles de mouse y teclado, gamepads y controles táctiles. Puedes ver cada uno de estos tipos de entrada en ReplicatedStorageUserInputHandler.

Este script cliente utiliza ContextActionService para vincular MouseButton1 y ButtonR2 a la acción de explosión. Esto significa que cada vez que un jugador presiona el botón izquierdo del mouse o el botón R2 de un gamepad, se activa un rayo láser que sale del blaster. Ten en cuenta que el HUDGui contiene un botón para explosionar en dispositivos móviles, que se conecta más adelante en el script.

UserInputHandler

ContextActionService:BindAction("_", onBlasterActivated, false,
Enum.UserInputType.MouseButton1,
Enum.KeyCode.ButtonR2
)

Otra nota importante es el uso de Enum.UserInputState.Begin en la definición de onBlasterActivated(). Muchas interacciones de la interfaz de usuario, como elegir un blaster en este ejemplo, no ocurren hasta que el botón del mouse se levanta (Enum.UserInputState.End), lo que da a los usuarios una última oportunidad de evitar la interacción. Sin embargo, una mecánica de explosión no se siente receptiva a menos que ocurra en el instante en que se presiona el botón.

Para demostrar, puedes cambiar Enum.UserInputState.Begin a Enum.UserInputState.End, y luego probar el juego para ver cómo la receptividad de la explosión impacta en el juego de la experiencia. Por ejemplo, si los jugadores pueden mantener presionado el botón sin activar la explosión, ¿cómo podría eso cambiar su experiencia al etiquetar a otros jugadores?

UserInputHandler

local function onBlasterActivated(_actionName: string,
inputState: Enum.UserInputState, _inputObject: InputObject)
if inputState == Enum.UserInputState.End then -- línea actualizada, asegúrate de cambiar de regreso
attemptBlastClient()
end
end

Comprobar si el jugador puede explosionar

Después de que UserInputHandler detecta una pulsación de botón o un toque en la pantalla, llama a ReplicatedStorageBlasterattemptBlastClient para comprobar si el jugador puede explosionar o no. Como la mayoría de las comprobaciones en la experiencia de láser tag de muestra, se realiza dos veces: primero en el cliente y luego en el servidor. attemptBlastClient luego llama a ReplicatedStorageBlastercanLocalPlayerBlast para realizar una comprobación simple del atributo blasterStateClient del jugador:

canLocalPlayerBlast

local function canLocalPlayerBlast(): boolean
return localPlayer:GetAttribute(PlayerAttribute.blasterStateClient) == BlasterState.Ready
end

Si examinas ReplicatedStorageBlasterBlasterState, puedes ver que la experiencia tiene tres estados de blaster: Ready, Blasting y Disabled. Para ver el efecto de cada uno de estos estados, puedes probar la experiencia, seleccionar tu jugador en el servicio Players, y luego observar el atributo blasterStateClient en la ventana de Properties. Nota cómo muestra Disabled mientras eliges tu blaster, Ready la mayor parte del tiempo, y Blasting durante menos de un segundo después de que presionas el botón.

Esta breve pausa te impide explosionar tan rápido como puedes hacer clic. Por ejemplo, si cambias la función para que siempre devuelva verdadero, puedes explosionar tu blaster rápidamente sin ningún retraso, lo cual es poco realista para la mecánica de juego de láser tag.

canLocalPlayerBlast

local function canLocalPlayerBlast(): boolean
return true -- línea actualizada, asegúrate de cambiar de regreso
end

Generar datos de explosión

Después de verificar que el blaster del jugador está en el estado Ready, attemptBlastClient llama a ReplicatedStorageattemptBlastClientblastClient. El primer paso que toma blastClient es establecer el atributo del jugador blasterStateClient en Blasting, lo que evita el mismo caso de disparo rápido de antes.

El siguiente paso es generar los datos de explosión. Si revisas ReplicatedStorageBlasterBlastData, puedes ver que cada explosión consiste en tres piezas de información:

  • El jugador que inicia la explosión.
  • Un DataType.CFrame que representa el punto de origen de la explosión.
  • Una tabla RayResult que contiene el destino final de cada rayo láser y el jugador impactado, si es que impactó a otro jugador.

Para generar estos datos, blastClient llama a ReplicatedStorageattemptBlastClientblastClientgenerateBlastData, que puedes revisar a continuación.

generateBlastData

local function generateBlastData(): BlastData.Type
local blasterConfig = getBlasterConfig()
local rayDirections = getDirectionsForBlast(
currentCamera.CFrame, blasterConfig)
local rayResults = castLaserRay(
localPlayer, currentCamera.CFrame.Position, rayDirections)
local blastData: BlastData.Type = {
player = localPlayer,
originCFrame = currentCamera.CFrame,
rayResults = rayResults,
}
return blastData
end

Esta función comienza utilizando getBlasterConfig para recuperar el tipo de blaster del jugador. La muestra proporciona dos tipos de blasters: uno que produce varios rayos con una dispersión horizontal amplia, y otro que produce un solo rayo. Puedes encontrar sus configuraciones en ReplicatedStorageInstancesLaserBlastersFolder.

La función luego utiliza currentCamera.CFrame como el punto de origen para la explosión, pasándolo a getDirectionsForBlast. En este punto, el código ya no se trata del blaster, se trata del rayo láser, sobre el cual aprenderás más en la sección detectar impactos del tutorial. Finalmente, después de crear la tabla rayResults, generateBlastData tiene toda la información que necesita para devolver los datos de explosión a blastClient.

Notificar al servidor

Una vez que blastClient tiene los datos completos de la explosión, dispara dos eventos:

blastClient

local laserBlastedBindableEvent = ReplicatedStorage.Instances.LaserBlastedBindableEvent
local laserBlastedEvent = ReplicatedStorage.Instances.LaserBlastedEvent
laserBlastedBindableEvent:Fire(blastData)
laserBlastedEvent:FireServer(blastData)

El BindableEvent notifica a otros scripts cliente sobre la explosión. Por ejemplo, ReplicatedStorageFirstPersonBlasterVisuals utiliza este evento para saber cuándo mostrar efectos visuales, como la animación de explosión y la barra de enfriamiento. De manera similar, el RemoteEvent notifica a los scripts del servidor sobre la explosión, que comienza a procesar la explosión en ServerScriptServiceLaserBlastHandler.

LaserBlastHandler

local function onLaserBlastedEvent(playerBlasted: Player, blastData: BlastData.Type)
local validatedBlastData = getValidatedBlastData(playerBlasted, blastData)
if not validatedBlastData then
return
end
if not canPlayerBlast(playerBlasted) then
return
end
blastServer(playerBlasted)
processTaggedPlayers(playerBlasted, blastData)
for _, replicateToPlayer in Players:GetPlayers() do
if playerBlasted == replicateToPlayer then
continue
end
replicateBlastEvent:FireClient(replicateToPlayer, playerBlasted, blastData)
end
end

Para ayudar a prevenir trampas, el servidor debe verificar todos los datos que cada cliente envía. Estas comprobaciones incluyen:

  1. ¿Es BlastData una tabla? ¿Contiene un Class.CFrame y otra tabla llamada rayResults?
  2. ¿El jugador tiene un blaster equipado?
  3. ¿El jugador tiene un personaje y una ubicación dentro del mundo?
  4. Después de enviar los datos de explosión, ¿el jugador se ha movido a una distancia excesiva desde donde disparó el rayo láser?

Esta última comprobación implica un juicio, y de acuerdo a la latencia del servidor y la velocidad de movimiento del jugador, puedes decidir que diferentes valores son excesivos para tu propia experiencia. Para demostrar cómo hacer este juicio, puedes tener una idea de la magnitud típica del cambio posicional agregando una declaración de impresión en getValidatedBlastData y probando la experiencia.

getValidatedBlastData

local distanceFromCharacterToOrigin = blastData.originCFrame.Position - rootPartCFrame.Position
print(distanceFromCharacterToOrigin.Magnitude) -- línea actualizada, asegúrate de eliminar
if distanceFromCharacterToOrigin.Magnitude > ToleranceValues.DISTANCE_SANITY_CHECK_TOLERANCE_STUDS then
warn(`Player {player.Name} failed an origin sanity check while blasting`)
return
end

A medida que te mueves y explotas, nota la salida. Podrías ver algo como esto:


1.9019629955291748
3.1549558639526367
2.5742883682250977
4.8044586181640625
2.6434271335601807

Si aumentas la velocidad de movimiento para los jugadores en ReplicatedStoragePlayerStateHandlertogglePlayerMovement, entonces prueba el juego nuevamente; es probable que encuentres muchas comprobaciones fallidas debido a movimiento excesivo entre explosiones.

togglePlayerMovement

local ENABLED_WALK_SPEED = 60 -- línea actualizada, asegúrate de cambiar de regreso

El servidor luego hace lo siguiente:

  • Valida rayResults.
  • Comprueba si el jugador puede explosionar.
  • Restablece el estado del blaster.
  • Reduce la salud de cualquier jugador etiquetado.
  • Replica la explosión a todos los demás jugadores para que puedan ver efectos visuales en tercera persona.

Para más información sobre estas operaciones del servidor, consulta la sección detectar impactos del tutorial.

Restablecer el blaster

En la experiencia de láser tag de muestra, los blasters utilizan una mecánica de calor. En lugar de recargar después de un número establecido de explosiones, necesitan tiempo para "enfriarse" entre cada explosión. Este mismo retraso de enfriamiento ocurre tanto en el cliente (blastClient) como en el servidor (blastServer), siendo el servidor la fuente de verdad.

blastServer

local blasterConfig = getBlasterConfig(player)
local secondsBetweenBlasts = blasterConfig:GetAttribute("secondsBetweenBlasts")
task.delay(secondsBetweenBlasts, function()
local currentState = player:GetAttribute(PlayerAttribute.blasterStateServer)
if currentState == BlasterState.Blasting then
player:SetAttribute(PlayerAttribute.blasterStateServer, BlasterState.Ready)
end
end)

El atributo secondsBetweenBlasts es parte de la configuración del blaster en ReplicatedStorageInstancesLaserBlastersFolder. Después de que pasa el retraso de secondsBetweenBlasts, el jugador puede explosionar nuevamente, y todo el proceso se repite. Para ayudar al jugador a entender cuándo puede explosionar de nuevo, la experiencia incluye una barra de enfriamiento.

En este punto, los jugadores pueden aparecer y reaparecer, apuntar y explosionar, pero la experiencia aún tiene que determinar los resultados de cada explosión. En la siguiente sección del tutorial, aprenderás cómo programar la capacidad del blaster para detectar cuándo la explosión impacta a otro jugador y luego reducir la cantidad apropiada de salud del jugador de acuerdo con la configuración del blaster.

©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.