Adicionar rodadas permite que você estruture o jogo em fases com um ponto de início e término claro para que os jogadores possam medir seu progresso e tenham uma oportunidade periódica de ter um campo de jogo igual.Isso é particularmente importante para jogos baseados em equipes porque oferece aos jogadores a chance de mudar seu estilo de jogo dependendo de quem está em sua equipe durante essa rodada.
Usando a experiência de etiqueta de laser de amostra como referência, esta seção do tutorial ensina você a usar e personalizar os recursos integrados do Roblox para estruturar cada rodada, incluindo orientações de script sobre:
- Começar uma rodada redefinindo pontos individuais e de equipe, então gerando jogadores em suas zonas de spawn de equipe.
- Personalizar variáveis que definem o objetivo para a rodada no topo da tela de cada jogador.
- Acompanhar contribuições de pontos do jogador para a pontuação de sua equipe.
- Ativando telas de UI únicas dependendo se a equipe do jogador ganhou ou perdeu a rodada.
- Terminar uma rodada desconectando os jogadores e gerando-os no lobby neutro.
Depois de concluir esta seção, você aprenderá a implementar o comportamento do blaster que seja tanto preciso quanto satisfatório para os jogadores.

Começar loop
Serviço de Script de Servidor > Jogabilidade > Rodadas lida com a maior parte da lógica para implementar rodadas e começa chamando a função startRoundLoopAsync() para marcar o início de um ciclo de rodadas.Enquanto os jogadores entram no lobby e esperam para se organizar em uma Equipe, chama a função no Serviço de Script de Servidor > Jogabilidade > Pontuação para redefinir tanto a tabela de classificação quanto os pontos da equipe.
Avaliação
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
Agora que todos estão começando em pontos zero, então define a propriedade Neutral da localização de spawn neutra para falso para que apenas jogadores com a mesma propriedade da localização de spawn só possam aparecer lá.Porque a propriedade do local de spawn TeamColor é definida como branco em vez das equipes de menta ou carnation rosa da amostra, esta configuração impede que todos os jogadores apareçam ou reapareçam lá enquanto uma rodada estiver ativa.
Para jogadores que estão atualmente no lobby, startRoundLoopAsync() passes todos os jogadores atualmente dentro da experiência para a função spawnPlayersInMap em Serviço de Script de Servidor > Jogabilidade > Rodadas > spawnPlayersInMap para classificar e equilibrar todos em uma equipe com aproximadamente o mesmo número de jogadores.
Para quaisquer novos jogadores que se juntam à experiência depois que o grupo do lobby foi organizado em uma Equipe, startRoundLoopAsync() ouça o evento Players.PlayerAdded:Connect e chame novamente a função spawnPlayersInMap para adicioná-los à equipe com a menor quantidade de jogadores.Para mais informações sobre esse processo, veja Configurar locais de spawn na seção anterior Spawning e Respawning do Tutorial.
Rodadas
-- Gerar todos os jogadores no mapa
neutralSpawn.Neutral = false
spawnPlayersInMap(Players:GetPlayers())
-- Gerar novos jogadores no mapa quando eles se juntam
local playerAddedConnection = Players.PlayerAdded:Connect(function(player: Player)
spawnPlayersInMap({ player })
end)
Definir objetivo
Agora que cada jogador está na arena com seus companheiros de equipe, a experiência precisa fornecer instruções para o que fazer para ser bem-sucedida dentro da rodada.A experiência de tag de laser de amostra aborda esse requisito fornecendo um prompt objetivo na parte superior da tela de cada jogador com orientações claras sobre o que a equipe precisa fazer para ganhar.

Embora você possa aprender mais sobre como configurar e exibir o componente de Interface de Usuário do Objetivo na UI Curriculum, esta seção se concentra em como implementar o objetivo do objetivo à medida que a rodada começa, começando com como definir a quantidade de pontos que cada equipe precisa para completar a rodada.
Embora o prompt de objetivo em tempo de execução informe os jogadores que precisam marcar três pontos para vencer, se você examinar o prompt em StarterGui > HUDGui , você pode ver que ele contém, em vez disso, um configurável " %d " para o valor do ponto.

“ ” é uma string de espaço reservado que você pode aumentar ou diminuir a qualquer momento para atender às suas próprias exigências de jogabilidade atualizando a variável ” em ReplicatedStorage > TEAM_SCORE_LIMIT .Por exemplo, se você definir esse número para um excessivamente alto 200 , o contador de pontos de solicitação e equipe atualizaria de acordo.
Limite de pontuação de equipe_SCORE_LIMIT
local TEAM_SCORE_LIMIT = 200 -- linha atualizada, certifique-se de mudar de voltarreturn TEAM_SCORE_LIMIT

Essa simples atualização de variáveis funciona em tempo de execução porque, quando a rodada começa, ReplicatedStorage > HUDGuiSetup > Definir Meta objetiva requer o script do módulo , para que possa trocar a string de espaço reservado na objetiva do Objetoda interface do usuário.
Limite de pontuação de equipe_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
Pontos de rastro
Agora que os jogadores têm um objetivo para a rodada, a experiência precisa acompanhar os pontos de cada Equipeaté que eles atinjam seu objetivo.Enquanto o comportamento padrão do serviço Teams grupa automaticamente cada jogador sob o time deles e soma as contribuições de cada jogador para a pontuação do time, é importante armazenar e monitorar pontos em um local separado para o jogo baseado em rodadas porque, se um jogador marcar e sair antes que a rodada termine, suas contribuições sejam deduzidas da tabela de classificação assim que eles se desconectarem da experiência.
Para garantir que isso não aconteça e que cada contribuição para o objetivo da equipe seja preservada, ReplicatedStorage > HUDGuiSetup > Iniciar sincronização de pontos de equipe armazena todos os pontos separadamente sob a atributo em serviço.Como teamPoints incrementos, este script de módulo chama a função startSyncingTeamPoints para encontrar o contador de equipes Class.GuiObjects dentro do componente da Interface de Propósito.
Quando localiza TeamACounter e TeamBCounter , obtém o atributo teamColor deles, que se correlaciona com as zonas de spawn de equipes: o TeamACounter exibe os pontos da Equipeverde e o TeamBCounter rastreia os pontos da Equiperosa.
Começar a sincronizar pontos de equipe
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)
O script do módulo então chama sua função de validar que o atributo menta do TeamACounter e o atributo carnation pink do TeamBCounter ambos correspondam às propriedades correspondentes do serviço.Se assim for, ele retorna ambas as equipes.
Começar a sincronizar pontos de equipe
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 isso ocorre, startSyncingTeamPoints define os objetos de ambos os contadores de equipe TextLabel em seus respectivos valores de teamPoints, e continua a atualizá-los sempre que um jogador marcar um ponto marcando outro jogador do Equipeoposto.
Começar a sincronizar pontos de equipe
teamPointCounter.TextLabel.Text = team:GetAttribute(GuiAttribute.teamPoints)
team:GetAttributeChangedSignal(GuiAttribute.teamPoints):Connect(function()
teamPointCounter.TextLabel.Text = team:GetAttribute(GuiAttribute.teamPoints)
Tudo nesta seção até agora se concentrou em como rastrear pontos na tela do jogador, mas é importante revisar a lógica que lida com pontos de rastreamento no servidor para que ele saiba quando uma equipe atinge o objetivo e ganha a rodada.Se você revisitar Serviço de Script de Servidor > Jogabilidade > Pontuação , você pode ver que o script do módulo começa criando um evento vinculável, que disparará sempre que um jogador marcar um ponto.
Avaliação
local teamScoreChangedBindable = Instance.new("BindableEvent")local Scoring = {teamScoreChanged = teamScoreChangedBindable.Event,}
Então, chama a função incrementScore, que realiza as seguintes ações:
- Pega o time do jogador e o valor atual de pontos de time no objeto no serviço, então adiciona um.
- Pega a pontuação individual do jogador na tabela de classificação e adiciona uma.
- Dispara o evento mencionado anteriormente com ambas as equipes do jogador e sua pontuação.
Esse processo mantém efetivamente o cliente e o servidor alinhados em relação às pontuações individuais de ambos os jogadores e às pontuações de equipe deles.
Avaliação
function Scoring.incrementScore(player: Player, amount: number)
local team = player.Team
assert(team, `Player {player.Name} must be on a team to score a point, but has no team`)
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
Exibir resultados
À medida que os jogadores marcam um ao outro e pontuam pontos para sua Equipe, Serviço de Script de Servidor > Jogabilidade > Rodadas verifica se a equipe que marcou atendeu ao objetivo da rodada.Se a pontuação da equipe for inferior à variável TEAM_SCORE_LIMIT na ReplicatedStorage > TEAM_SCORE_LIMIT , o servidor continua esperando até que uma das equipes marque novamente.
No entanto, uma vez que a pontuação de uma Equipechegue à variável TEAM_SCORE_LIMIT, o script atira uma instância de evento roundWinnerRemote com o nome do jogador e sua Equipe.
Rodadas
-- Verifique se a rodada terminou após cada pontuaçãolocal team: Teamlocal score: number = 0while score < TEAM_SCORE_LIMIT doteam, score = Scoring.teamScoreChanged:Wait()end-- Exibir Equipevencedorafor _, player in Players:GetPlayers() do-- Enviar para qual equipe o jogador está no final da rodada-- pois a equipe do jogador está prestes a ser removida, então o cliente-- não será possível verificar sua própria equiperoundWinnerRemote:FireClient(player, team, player.Team)end
O script ReplicatedStorage > RoundResultsGuiSetup em cada lista de clientes ouve essa instância de evento para que possa:
- Exibe uma interface de usuário única StarterGui > RoundResultsGui que anuncia os resultados da rodada e se o jogador estava na Equipevencedora.
- Reproduza um áudio de vitória ou derrota.
Por exemplo, se um jogador está na equipe que marcou o ponto vencedor, eles recebem múltiplas formas de feedback sobre os resultados da rodada na forma de uma tela de UI que exibe o texto da vitória e um áudio que toca um som alegre.Inversamente, se um jogador não está na equipe que marcou o ponto vencedor, ele recebe uma tela de UI que exibe o texto da derrota e um arquivo de áudio que toca um som sinistro.
Configuração do RoundResultsGui
local function onRoundWinner(winner: Team, localTeam: Team?)
local victoryDefeatText = "Round ended!"
if localTeam then
-- Se a nossa equipe vencer, mostraremos Vitória! Caso contrário, mostraremos Derrota...
local isVictory = winner == localTeam
if isVictory then
victorySound:Play()
victoryDefeatText = VICTORY_TEXT
else
defeatSound:Play()
victoryDefeatText = DEFEAT_TEXT
end
end
Redefinir equipes
Ao mesmo tempo que Serviço de Script de Servidor > Jogabilidade > Rodadas verifica que uma equipe atingiu o objetivo da rodada e aciona a exibição de UI apropriada para cada jogador, também transporta todos os jogadores da arena para o lobby desconectando-os da rodada.Isso inicia o processo de encerrar formalmente a rodada e reiniciar ambas as equipes.
Usando a mesma lógica em Configurar locais de spawn, Rodadas então define a propriedade Neutral da localização de spawn Neutral para verdadeira para que os jogadores possam aparecer lá independentemente do status de sua equipe.Isso significa que o lobby se torna a única localização em que os jogadores podem aparecer depois de serem desconectados da rodada.
Rodadas
-- Envie todos para o lobbyplayerAddedConnection:Disconnect()neutralSpawn.Neutral = truespawnPlayersInLobby(Players:GetPlayers())
Depois de esperar dez segundos por uma intermissão, o script do servidor Rounds então inicia o ciclo novamente, redefinindo as pontuações de todos e organizando-as em novas equipes.A amostra repete esse processo cíclico até que não haja nenhum jogador dentro do servidor.
Agora que os jogadores podem aparecer no mapa com sua própria equipe e jogar uma rodada completa, a próxima seção ensina você sobre os scripts por trás do comportamento de cada blaster.