Aggiungi turni

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

Aggiungere turni consente di strutturare il gameplay in fasi con un chiaro inizio e una fine in modo che i giocatori possano misurare i loro progressi e avere un'opportunità periodica per un campo di gioco equo. Questo è particolarmente importante per il gameplay basato su squadre, poiché offre ai giocatori la possibilità di cambiare il proprio stile di gioco a seconda di chi è nella loro squadra durante quel turno.

Usando l'esperienza di laser tag campione come riferimento, questa sezione del tutorial ti insegna come utilizzare e personalizzare le funzionalità integrate di Roblox per strutturare ciascun turno, inclusi suggerimenti di scripting su:

  • Iniziare un turno resettando i punti individuali e di squadra, quindi facendo apparire i giocatori nelle zone di spawn della loro squadra.
  • Personalizzare le variabili che impostano l'obiettivo per il turno nella parte superiore dello schermo di ciascun giocatore.
  • Monitorare i contributi di punti dei giocatori per il punteggio della loro squadra.
  • Attivare schermi UI unici a seconda che la squadra del giocatore abbia vinto o perso il turno.
  • Terminate un turno disconnettendo i giocatori e facendo apparire in una lobby neutrale.

Dopo aver completato questa sezione, imparerai come implementare un comportamento dei blaster che sia sia accurato che soddisfacente per i giocatori.

Iniziare il ciclo

ServerScriptServiceGameplayRounds gestisce la maggior parte della logica per implementare i turni e inizia chiamando la funzione startRoundLoopAsync() per segnare l'inizio di un ciclo di turni. Mentre i giocatori si uniscono alla lobby e aspettano di essere distribuiti in una squadra, startRoundLoopAsync() chiama la funzione resetScores() in ServerScriptServiceGameplayScoring per resettare sia la classifica che i punti di squadra.

Scoring

function Scoring.resetScores()
for _, player in Players:GetPlayers() do
player.leaderstats.Points.Value = 0
end
for _, team in Teams:GetTeams() do
team:SetAttribute(GuiAttribute.teamPoints, 0)
end
end

Ora che tutti partono da zero punti, startRoundLoopAsync() imposta quindi la proprietà Neutral della posizione di spawn Neutra su false in modo che solo i giocatori con la stessa proprietà Team.Color della proprietà TeamColor della posizione di spawn possano apparire lì. Poiché la proprietà TeamColor della posizione di spawn è impostata su bianco invece che sui campioni di menta o rosa carne, questa configurazione impedisce a tutti i giocatori di spawnare o riapparire lì mentre un turno è attivo.

Per i giocatori che si trovano attualmente nella lobby, startRoundLoopAsync() passa tutti i giocatori attualmente all'interno dell'esperienza alla funzione spawnPlayersInMap in ServerScriptServiceGameplayRoundsspawnPlayersInMap per distribuire e bilanciare tutti in una squadra con un numero approssimativo di giocatori.

Per tutti i nuovi giocatori che si uniscono all'esperienza dopo che il gruppo della lobby è stato suddiviso in una squadra, startRoundLoopAsync() ascolta l'evento Players.PlayerAdded:Connect, quindi chiama nuovamente la funzione spawnPlayersInMap per aggiungerli alla squadra con il minor numero di giocatori. Per maggiori informazioni su questo processo, vedere Configura le Posizioni di Spawn dalla sezione precedente Spawn e Riapparizione del tutorial.

Rounds

-- Spawn di tutti i giocatori nella mappa
neutralSpawn.Neutral = false
spawnPlayersInMap(Players:GetPlayers())
-- Spawn nuovi giocatori nella mappa quando si uniscono
local playerAddedConnection = Players.PlayerAdded:Connect(function(player: Player)
spawnPlayersInMap({ player })
end)

Imposta obiettivo

Ora che ogni giocatore si trova nell'arena con i propri compagni di squadra, l'esperienza deve fornire istruzioni su cosa fare per avere successo all'interno del turno. L'esperienza di laser tag campione affronta questo requisito fornendo un prompt obiettivo nella parte superiore dello schermo di ciascun giocatore con chiari indicazioni su cosa deve fare la squadra per vincere.

Sebbene tu possa imparare di più su come configurare e visualizzare il componente UI Obiettivo nel Curriculum UI, questa sezione si concentra su come implementare l'obiettivo all'inizio del turno, iniziando da come impostare la quantità di punti che ciascuna squadra deve completare per il turno.

Anche se il prompt obiettivo durante l'esecuzione informa i giocatori che devono segnare tre punti per vincere, se esamini il prompt in StarterGuiHUDGui, puoi vedere che contiene invece una configurazione "%d" per il valore dei punti.

"%d" è una stringa segnaposto che puoi aumentare o diminuire in qualsiasi momento per soddisfare le tue esigenze di gioco aggiornando la variabile TEAM_SCORE_LIMIT in ReplicatedStorageTEAM_SCORE_LIMIT. Ad esempio, se impostassi questo numero su un eccessivamente alto 200, il prompt e il contatore dei punti di squadra verrebbero aggiornati di conseguenza.

TEAM_SCORE_LIMIT

local TEAM_SCORE_LIMIT = 200 -- riga aggiornata, assicurati di cambiare di nuovo
return TEAM_SCORE_LIMIT

Questo semplice aggiornamento della variabile funziona durante l'esecuzione perché, all'inizio del turno, ReplicatedStorageHUDGuiSetupSetObjective richiede lo script di modulo TEAM_SCORE_LIMIT in modo da poter scambiare la stringa segnaposto nell'oggetto TextLabel dell'Obiettivo UI.

TEAM_SCORE_LIMIT

local TEAM_SCORE_LIMIT = require(ReplicatedStorage.TEAM_SCORE_LIMIT)
local function setObjective(gui: ScreenGui)
local bodyTextLabel = gui.Objective.ObjectiveDisplay.Body.BodyTextLabel
bodyTextLabel.Text = bodyTextLabel.Text:format(TEAM_SCORE_LIMIT)
end

Tieni traccia dei punti

Ora che i giocatori hanno un obiettivo per il turno, l'esperienza deve tenere traccia dei punti di ciascuna squadra finché non raggiungono il loro obiettivo. Mentre il comportamento predefinito del servizio Teams raggruppa automaticamente ciascun giocatore sotto la propria squadra e somma i contributi di ciascun giocatore al punteggio della loro squadra, è importante memorizzare e monitorare i punti in un luogo separato per il gameplay basato su turni, perché se un giocatore segna e poi esce prima che il turno sia finito, il loro contributo viene dedotto dalla classifica non appena si disconnette dall'esperienza.

Per garantire che ciò non accada e che ogni contributo verso l'obiettivo della squadra sia preservato, ReplicatedStorageHUDGuiSetupStartSyncingTeamPoints memorizza tutti i punti separatamente sotto l'attributo teamPoints nel servizio Teams. Man mano che teamPoints aumenta, questo modulo script chiama la funzione startSyncingTeamPoints per trovare il contatore di squadra Class.GuiObjects all'interno del componente UI Obiettivo.

Quando trova TeamACounter e TeamBCounter, ottiene il loro attributo teamColor, che corrisponde alle zone di spawn della squadra: TeamACounter visualizza i punti della squadra verde e TeamBCounter tiene traccia dei punti della squadra rosa.

StartSyncingTeamPoints

local function startSyncingTeamPoints(gui: ScreenGui)
for _, teamPointCounter in gui.Objective.TeamPointCounter:GetChildren() do
if not teamPointCounter:IsA("GuiObject") then
continue
end
local iconTeamColor = teamPointCounter:GetAttribute(GuiAttribute.teamColor)

Il modulo script chiama quindi la sua funzione getTeamFromTeamColor per convalidare che l'attributo teamColor menta del TeamACounter e l'attributo teamColor rosa carne del TeamBCounter corrispondano entrambi alle proprietà Team.Color corrispondenti sotto il servizio Teams. Se sì, restituisce entrambe le squadre.

StartSyncingTeamPoints

local function getTeamFromTeamColor(teamColor: Color3): Team?
for _, team in Teams:GetTeams() do
if team.TeamColor == teamColor then
return team
end
end
return nil
end

Quando ciò accade, startSyncingTeamPoints imposta gli oggetti TextLabel di entrambi i contatori di squadra sui loro valori corrispondenti di teamPoints e continua ad aggiornarli ogni volta che un giocatore segna un punto eliminando un altro giocatore della squadra avversaria.

StartSyncingTeamPoints

teamPointCounter.TextLabel.Text = team:GetAttribute(GuiAttribute.teamPoints)
team:GetAttributeChangedSignal(GuiAttribute.teamPoints):Connect(function()
teamPointCounter.TextLabel.Text = team:GetAttribute(GuiAttribute.teamPoints)

Finora tutto ciò che è stato trattato in questa sezione si è concentrato su come monitorare i punti nello schermo del giocatore, ma è importante rivedere la logica che gestisce il monitoraggio dei punti sul server in modo che sappia quando una squadra raggiunge l'obiettivo e vince il turno. Se torni a ServerScriptServiceGameplayScoring, puoi vedere che il modulo script inizia creando un evento bindable, che verrà attivato ogni volta che un giocatore segna un punto.

Scoring

local teamScoreChangedBindable = Instance.new("BindableEvent")
local Scoring = {
teamScoreChanged = teamScoreChangedBindable.Event,
}

Chiama quindi la funzione incrementScore, che esegue le seguenti azioni:

  • Ottiene la squadra del giocatore e il loro attuale valore di teamPoints nell'oggetto Team nel servizio Teams, quindi aggiunge uno.
  • Ottiene il punteggio individuale del giocatore nella classifica e aggiunge uno.
  • Attiva l'evento bindable precedentemente menzionato sia con la squadra del giocatore che con il loro punteggio.

Questo processo mantiene effettivamente allineati sia il client che il server riguardo ai punteggi individuali dei giocatori e ai punteggi della loro squadra.

Scoring

function Scoring.incrementScore(player: Player, amount: number)
local team = player.Team
assert(team, `Il giocatore {player.Name} deve essere in una squadra per segnare un punto, ma non ha una squadra`)
local teamPoints = team:GetAttribute(GuiAttribute.teamPoints)
teamPoints += amount
team:SetAttribute(GuiAttribute.teamPoints, teamPoints)
local leaderstat = player.leaderstats.Points
leaderstat.Value += amount
teamScoreChangedBindable:Fire(team, teamPoints)
end

Visualizza i risultati

Man mano che i giocatori si eliminano a vicenda e segnano punti per la loro squadra, ServerScriptServiceGameplayRounds verifica se la squadra che ha segnato ha soddisfatto l'obiettivo del turno. Se il punteggio della loro squadra è inferiore alla variabile TEAM_SCORE_LIMIT in ReplicatedStorageTEAM_SCORE_LIMIT, il server continua ad aspettare fino a quando una delle squadre non segna di nuovo.

Tuttavia, una volta che il punteggio di una squadra raggiunge la variabile TEAM_SCORE_LIMIT, lo script attiva un'istanza di evento roundWinnerRemote con il nome del giocatore e la loro squadra.

Rounds

-- Controlla se il turno è finito dopo ogni punteggio
local team: Team
local score: number = 0
while score < TEAM_SCORE_LIMIT do
team, score = Scoring.teamScoreChanged:Wait()
end
-- Visualizza la squadra vincente
for _, player in Players:GetPlayers() do
-- Inviando a quale squadra il giocatore appartiene alla fine del turno
-- perché la squadra del giocatore sta per essere rimossa, quindi il client
-- non sarà in grado di controllare la propria squadra
roundWinnerRemote:FireClient(player, team, player.Team)
end

Lo script ReplicatedStorageRoundResultsGuiSetup su ciascun client ascolta per questo evento roundWinnerRemote in modo da poter:

  • Visualizzare un'unica schermata UI StarterGuiRoundResultsGui che annuncia i risultati del turno e se il giocatore era sulla squadra vincente.
  • Riprodurre un clip audio di vittoria o sconfitta.

Ad esempio, se un giocatore è nella squadra che ha segnato il punto vincente, riceve molte forme di feedback sui risultati del turno sotto forma di una schermata UI che visualizza un testo di vittoria e un clip audio che riproduce un suono gioioso. Al contrario, se un giocatore non è nella squadra che ha segnato il punto vincente, riceve una schermata UI che visualizza un testo di sconfitta e un clip audio che riproduce un suono minaccioso.

Feedback di vittoria
Feedback di sconfitta
RoundResultsGuiSetup

local function onRoundWinner(winner: Team, localTeam: Team?)
local victoryDefeatText = "Il turno è finito!"
if localTeam then
-- Se la nostra squadra ha vinto, visualizzeremo Vittoria! Altrimenti visualizziamo Sconfitta...
local isVictory = winner == localTeam
if isVictory then
victorySound:Play()
victoryDefeatText = VICTORY_TEXT
else
defeatSound:Play()
victoryDefeatText = DEFEAT_TEXT
end
end

Resetta le squadre

Allo stesso tempo in cui ServerScriptServiceGameplayRounds verifica che una squadra abbia soddisfatto l'obiettivo del turno e attiva la visualizzazione UI appropriata per ciascun giocatore, trasporta anche tutti i giocatori dall'arena alla lobby disconnettendoli dal turno. Questo avvia il processo di conclusione formale del turno e ripristino di entrambe le squadre.

Utilizzando la stessa logica in Configura Posizioni di Spawn, Rounds imposta quindi la proprietà Neutral della posizione di spawn Neutra su true in modo che i giocatori possano spawnare lì indipendentemente dal loro stato nella squadra. Questo significa che la lobby diventa l'unico luogo in cui i giocatori possono spawnare dopo essere stati disconnessi dal turno.

Rounds

-- Invia tutti nella lobby
playerAddedConnection:Disconnect()
neutralSpawn.Neutral = true
spawnPlayersInLobby(Players:GetPlayers())

Dopo aver atteso dieci secondi per una interruzione, lo script del server Rounds inizia quindi di nuovo il ciclo resettando i punteggi di tutti e distribuendoli in nuove squadre. Il campione ripete questo processo ciclico di turni fino a quando non ci sono più giocatori nel server.

Ora che i giocatori possono spawnare nella mappa con la propria squadra e giocare un intero turno, la prossima sezione ti insegna gli script dietro il comportamento di ciascun 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.