Implementare il comportamento del blaster

*Questo contenuto è tradotto usando AI (Beta) e potrebbe contenere errori. Per visualizzare questa pagina in inglese, clicca qui.

Implementare il comportamento del blaster è il processo di programmazione di una meccanica di esplosione nei giochi sparatutto in prima persona. Mentre i giocatori possono esplodere con un singolo clic o pressione di un pulsante, creare un comportamento di esplosione soddisfacente e preciso è importante perché migliora il divertimento dei giocatori durante il gioco.

Utilizzando il gioco di laser tag di esempio come riferimento, questa sezione del tutorial ti insegna gli script dietro l'implementazione del comportamento del blaster per due diversi tipi di blaster, inclusa la guida su:

  • Rilevare quando i giocatori premere il pulsante di esplosione.
  • Controllare se il giocatore può utilizzare il proprio blaster se ha recentemente premuto il pulsante di esplosione.
  • Generare dati di esplosione che dicono al server chi ha iniziato l'esplosione, da dove è partita e qual è stata la destinazione finale di ciascun raggio laser.
  • Notificare il server dei dati di esplosione in modo che possa eseguire le azioni appropriate se l'esplosione ha colpito un altro giocatore.
  • Ripristinare il blaster tra ogni esplosione per dare al blaster abbastanza tempo per raffreddarsi prima di poter esplodere di nuovo.

Dopo aver completato questa sezione, imparerai a conoscere gli script che consentono al blaster di rilevare quando le sue esplosioni colpiscono altri giocatori, quindi dedurre la corrispondente quantità di salute in base a ciascun tipo di blaster.

Rilevare l'input del giocatore

Il primo passo per implementare il comportamento del blaster è ascoltare quando un giocatore preme il pulsante di esplosione. Il tipo di input che i giocatori utilizzano per premere il pulsante di esplosione dipende dal dispositivo che stanno utilizzando per accedere al gioco. Ad esempio, il gioco di laser tag di esempio supporta controlli con mouse e tastiera, gamepad e controlli touch. Puoi vedere ciascuno di questi tipi di input in ReplicatedStorageUserInputHandler.

Questo script client utilizza ContextActionService per associare MouseButton1 e ButtonR2 all'azione di esplosione. Ciò significa che ogni volta che un giocatore preme il pulsante sinistro del mouse o il pulsante R2 di un gamepad, si attiva un raggio laser che esplode dal blaster. Nota che il HUDGui contiene un pulsante per esplodere sui dispositivi mobili, che viene collegato più avanti nello script.

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

Un'altra nota importante è l'uso di Enum.UserInputState.Begin nella definizione di onBlasterActivated(). Molte interazioni dell'interfaccia utente, come la scelta di un blaster in questo esempio, non si verificano fino a dopo che il pulsante del mouse è stato rilasciato (Enum.UserInputState.End), il che dà agli utenti un'ultima possibilità di evitare l'interazione. Tuttavia, una meccanica di esplosione non sembra reattiva a meno che non si verifichi nel momento in cui il pulsante viene premuto.

Per dimostrare, puoi cambiare Enum.UserInputState.Begin in Enum.UserInputState.End, quindi fare un test di gioco per vedere come la reattività dell'esplosione influisce sul gameplay del gioco. Ad esempio, se i giocatori possono tenere premuto il pulsante senza attivare l'esplosione, come potrebbe cambiare la loro esperienza mentre colpiscono altri giocatori?

UserInputHandler
local function onBlasterActivated(_actionName: string,
inputState: Enum.UserInputState, _inputObject: InputObject)
if inputState == Enum.UserInputState.End then -- riga aggiornata, assicurati di cambiare di nuovo
attemptBlastClient()
end
end

Controllare se il giocatore può esplodere

Dopo che UserInputHandler rileva una pressione del pulsante o un tocco sullo schermo, chiama ReplicatedStorageBlasterattemptBlastClient per controllare se il giocatore può esplodere o meno. Come la maggior parte dei controlli nel gioco di laser tag di esempio, si verifica due volte: prima sul client, poi più tardi sul server. attemptBlastClient chiama quindi ReplicatedStorageBlastercanLocalPlayerBlast per eseguire un semplice controllo dell'attributo del giocatore blasterStateClient:

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

Se esamini ReplicatedStorageBlasterBlasterState, puoi vedere che il gioco ha tre stati del blaster: Ready, Blasting e Disabled. Per vedere l'effetto di ciascuno di questi stati, puoi fare un test di gioco, selezionare il tuo giocatore sotto il servizio Players, quindi osservare l'attributo blasterStateClient nella finestra Properties. Nota come mostra Disabled mentre scegli il tuo blaster, Ready per la maggior parte del tempo e Blasting per meno di un secondo dopo aver premuto il pulsante.

Questa leggera pausa ti impedisce di esplodere così rapidamente come puoi cliccare. Ad esempio, se cambi la funzione per restituire sempre true, puoi esplodere rapidamente il tuo blaster senza alcun ritardo, il che è irrealistico per il gameplay del laser tag.

canLocalPlayerBlast
local function canLocalPlayerBlast(): boolean
return true -- riga aggiornata, assicurati di cambiare di nuovo
end

Generare dati di esplosione

Dopo aver verificato che il blaster del giocatore è nello stato Ready, attemptBlastClient chiama ReplicatedStorageattemptBlastClientblastClient. Il primo passo che blastClient compie è impostare l'attributo del giocatore blasterStateClient su Blasting, il che evita il caso di fuoco rapido precedente.

Il passo successivo è generare i dati di esplosione. Se rivedi ReplicatedStorageBlasterBlastData, puoi vedere che ogni esplosione consiste in tre pezzi di informazione:

  • Il giocatore che inizia l'esplosione.
  • Un DataType.CFrame che rappresenta il punto di origine dell'esplosione.
  • Una tabella RayResult che contiene la destinazione finale di ciascun raggio laser e il giocatore colpito, se ha colpito un altro giocatore.

Per generare questi dati, blastClient chiama ReplicatedStorageattemptBlastClientblastClientgenerateBlastData, che puoi rivedere qui sotto.

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

Questa funzione inizia utilizzando getBlasterConfig per recuperare il tipo di blaster del giocatore. Il campione fornisce due tipi di blaster: uno che produce diversi raggi con una diffusione orizzontale ampia e un altro che produce un singolo raggio. Puoi trovare le loro configurazioni in ReplicatedStorageInstancesLaserBlastersFolder.

La funzione utilizza quindi currentCamera.CFrame come punto di origine per l'esplosione, passandolo a getDirectionsForBlast. A questo punto, il codice non riguarda più il blaster, ma il raggio laser, di cui imparerai di più nella sezione detect hits del tutorial. Infine, dopo aver creato la tabella rayResults, generateBlastData ha tutte le informazioni necessarie per restituire i dati di esplosione a blastClient.

Notificare il server

Una volta che blastClient ha dati completi per l'esplosione, attiva due eventi:

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

Il BindableEvent notifica altri script client dell'esplosione. Ad esempio, ReplicatedStorageFirstPersonBlasterVisuals utilizza questo evento per sapere quando visualizzare effetti visivi, come l'animazione dell'esplosione e la barra di raffreddamento. Allo stesso modo, il RemoteEvent notifica gli script del server dell'esplosione, che inizia a elaborare l'esplosione in 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

Per aiutare a prevenire le frodi, il server deve verificare tutti i dati che ciascun client invia. Questi controlli includono:

  1. È BlastData una tabella? Contiene un Class.CFrame e un'altra tabella chiamata rayResults?
  2. Il giocatore ha un blaster equipaggiato?
  3. Il giocatore ha un personaggio e una posizione all'interno del mondo?
  4. Dopo aver inviato i dati di esplosione, il giocatore si è spostato a una distanza eccessiva da dove ha esploso il raggio laser?

Questo ultimo controllo comporta una valutazione, e a seconda della latenza del server e della velocità di movimento del giocatore, potresti decidere che valori diversi sono eccessivi per il tuo gioco. Per dimostrare come fare questa valutazione, puoi avere un'idea della magnitudine tipica del cambiamento di posizione aggiungendo un'istruzione di stampa in getValidatedBlastData e testando il gioco.

getValidatedBlastData
local distanceFromCharacterToOrigin = blastData.originCFrame.Position - rootPartCFrame.Position
print(distanceFromCharacterToOrigin.Magnitude) -- riga aggiornata, assicurati di rimuovere
if distanceFromCharacterToOrigin.Magnitude > ToleranceValues.DISTANCE_SANITY_CHECK_TOLERANCE_STUDS then
warn(`Player {player.Name} failed an origin sanity check while blasting`)
return
end

Mentre ti muovi ed esplodi, nota l'output. Potrebbe apparire qualcosa del genere:

1.9019629955291748
3.1549558639526367
2.5742883682250977
4.8044586181640625
2.6434271335601807

Se aumenti la velocità di movimento per i giocatori in ReplicatedStoragePlayerStateHandlertogglePlayerMovement, quindi fai un altro test di gioco, probabilmente incontrerai molti controlli falliti a causa di movimenti eccessivi tra le esplosioni.

togglePlayerMovement
local ENABLED_WALK_SPEED = 60 -- riga aggiornata, assicurati di cambiare di nuovo

Il server quindi esegue le seguenti operazioni:

  • Valida rayResults.
  • Controlla se il giocatore può esplodere.
  • Ripristina lo stato del blaster.
  • Riduce la salute per eventuali giocatori colpiti.
  • Replica l'esplosione a tutti gli altri giocatori in modo che possano vedere effetti visivi in terza persona.

Per ulteriori informazioni su queste operazioni del server, consulta la sezione detect hits del tutorial.

Ripristinare il blaster

Nel gioco di laser tag di esempio, i blaster utilizzano una meccanica di calore. Piuttosto che ricaricare dopo un numero prestabilito di esplosioni, hanno bisogno di tempo per "raffreddarsi" tra ogni esplosione. Questo stesso ritardo di raffreddamento si verifica sia sul client (blastClient) che sul server (blastServer), con il server che funge da fonte di verità.

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)

L'attributo secondsBetweenBlasts fa parte della configurazione del blaster in ReplicatedStorageInstancesLaserBlastersFolder. Dopo che il ritardo di secondsBetweenBlasts è passato, il giocatore può esplodere di nuovo e l'intero processo si ripete. Per aiutare il giocatore a capire quando può esplodere di nuovo, il gioco include una barra di raffreddamento.

A questo punto, i giocatori possono apparire e riapparire, mirare ed esplodere, ma il gioco deve ancora determinare i risultati di ciascuna esplosione. Nella prossima sezione del tutorial, imparerai a programmare la capacità del blaster di rilevare quando l'esplosione colpisce un altro giocatore, quindi ridurre la quantità appropriata di salute del giocatore in base alle impostazioni del blaster.

© 2026 Roblox Corporation. Roblox, il logo Roblox e Powering Imagination sono tra i nostri marchi registrati e non registrati negli Stati Uniti. e altri paesi.