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 nelle esperienze di sparatutto in prima persona. Mentre i giocatori possono esplodere con un solo clic o pressione di un pulsante, creare un comportamento di esplosione soddisfacente e preciso è importante perché migliora il divertimento dei giocatori durante il gameplay complessivo.

Utilizzando l'esperienza 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 premendo il pulsante di esplosione.
  • Verificare se il giocatore può utilizzare il proprio blaster se ha recentemente premuto il pulsante di esplosione.
  • Generare dati di esplosione che indicano al server chi ha avviato l'esplosione, da dove è venuta e qual è stata la destinazione finale di ogni raggio laser.
  • Notificare il server dei dati di esplosione affinché possa svolgere le azioni appropriate se l'esplosione è collisa con un altro giocatore.
  • Ripristinare il blaster tra ogni esplosione per dare al blaster il tempo sufficiente 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 collidono con altri giocatori, quindi dedurre l'importo corrispondente di salute in base a ciascun tipo di blaster.

Rileva 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 all'esperienza. Ad esempio, l'esperienza 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 collegare 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, viene attivato un raggio laser che esplode dal blaster. Nota che il HUDGui contiene un pulsante per esplodere sui dispositivi mobili, che viene collegato successivamente 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 selezionare un blaster in questo esempio, non si verificano fino a dopo che il pulsante del mouse si alza (Enum.UserInputState.End), dando agli utenti un'ultima possibilità di evitare l'interazione. Tuttavia, una meccanica di esplosione non sembra reattiva a meno che non si verifichi istantaneamente nel momento in cui il pulsante viene premuto.

Per dimostrare, puoi cambiare Enum.UserInputState.Begin in Enum.UserInputState.End, quindi eseguire un test per vedere come la reattività dell'esplosione impatta il gameplay dell'esperienza. Ad esempio, se i giocatori possono tenere premuto il pulsante senza attivare l'esplosione, come potrebbe cambiare la loro esperienza nel colpire 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

Verifica se il giocatore può esplodere

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

canLocalPlayerBlast

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

Se esamini ReplicatedStorageBlasterBlasterState, puoi vedere che l'esperienza ha tre stati del blaster: Ready, Blasting e Disabled. Per vedere l'effetto di ciascuno di questi stati, puoi eseguire il test dell'esperienza, selezionare il tuo giocatore sotto il servizio Players, quindi osservare l'attributo blasterStateClient nella finestra Properties. Nota come visualizza 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 riesci a 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

Genera 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 precedentemente menzionato.

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

  • Il giocatore che avvia l'esplosione.
  • Un DataType.CFrame che rappresenta il punto di origine dell'esplosione.
  • Una tabella RayResult che contiene la destinazione finale di ogni 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. L'esempio fornisce due tipi di blaster: uno che produce diversi fasci con una diffusione orizzontale ampia e un altro che produce un singolo fascio. Puoi trovare le loro configurazioni in ReplicatedStorageInstancesLaserBlastersFolder.

La funzione usa poi 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 rileva colpi del tutorial. Infine, dopo aver creato la tabella rayResults, generateBlastData ha tutte le informazioni necessarie per restituire i dati di esplosione a blastClient.

Notifica il server

Una volta che blastClient ha i 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 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 imbroglio, 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?

Quest'ultimo controllo comporta una valutazione da parte del giudice e, secondo la latenza del server e la velocità di movimento del giocatore, potresti decidere che diversi valori sono eccessivi per la tua esperienza. Per dimostrare come fare questa valutazione, puoi farti un'idea della magnitudine tipica del cambiamento posizionale aggiungendo un'istruzione di stampa in getValidatedBlastData e testando l'esperienza.

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 e esplodi, prendi nota dell'output. Potrebbe assomigliare a questo:


1.9019629955291748
3.1549558639526367
2.5742883682250977
4.8044586181640625
2.6434271335601807

Se aumenti la velocità di movimento per i giocatori in ReplicatedStoragePlayerStateHandlertogglePlayerMovement, quindi esegui di nuovo il test, è probabile che tu incontri 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 qualsiasi giocatore contrassegnato.
  • Replica l'esplosione a tutti gli altri giocatori affinché possano vedere effetti visivi in terza persona.

Per ulteriori informazioni su queste operazioni del server, vedere la sezione rileva colpi del tutorial.

Ripristina il blaster

Nell'esperienza di laser tag di esempio, i blaster utilizzano una meccanica di calore. Anziché ricaricare dopo un numero impostato di esplosioni, hanno bisogno di tempo per "raffreddarsi" tra ciascuna esplosione. Questo stesso ritardo di cooldown 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 è trascorso, il giocatore può esplodere di nuovo e l'intero processo si ripete. Per aiutare il giocatore a capire quando può esplodere di nuovo, l'esperienza include una barra di raffreddamento.

A questo punto, i giocatori possono apparire e riapparire, mirare e esplodere, ma l'esperienza 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 l'importo appropriato di salute del giocatore secondo le 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.