Agora, muita da informação do jogo está na Janela de Saída, invisível para os jogadores. Para que os jogadores possam ser informados de o que está acontecendo no jogo, você criará uma interface gráfica de usuário (Interface gráfica do usuário) e o codificará.
Exibindo informações com uma Interface gráfica do usuário
Para este jogo, uma etiqueta de texto exibirá o status de jogo atual, bem como o número de jogadores restantes e o tempo.
Configurando o Interface gráfica do usuário
Primeiro, crie um objeto GUI da Tela para armazenar os diferentes elementos de texto. Quando o jogador mover a Câmera, o GUI da Tela fica no mesmo lugar na tela deles.
Para garantir que todos os jogadores vejam o mesmo display, coloque o GUI no StarterGui pasta. No momento do jogo, esta pasta é copiada para todos os jogadores.
Na pasta StarterGui, crie um novo ScreenGUI. Em seguida, na pasta ScreenGUI, adicione um novo TextLabel chamado StatusText.
Para mover a etiqueta / rótulo, no Explorador, selecione StatusText. Em seguida, na janela de visualização do jogo, arraste a etiqueta onde você gostaria que ela estivesse. Seus números podem diferir do vídeo. A etiqueta também pode ser reposicionada usando os pontos de ancoragem nas pontas.
Programando a Interface gráfica do usuário
Para refletir as alterações no jogo, scripts precisarão atualizar os elementos da GUI. Por instância, o status do jogo, se for uma intermissão ou uma rodada ativa, será armazenado em um StringValue e atualizado usando scripts locais.
Configurando o Script
O script StatusDisplay será usado para atualizar a GUI do jogador sempre que o estado do jogo mudar.
Em Armazenamento Replicado , crie um pasta chamado DisplayColors. Neste pasta, adicione um valor chamado Status. Para testar o valor mais tarde, dê um valor temporário, como "Bem-vindo à Batalha!".
In StarterGui > ScreenGUI > Status, adicione um novo script local chamado StatusDisplay. Scripts que afetam o GUI geralmente são vinculados a esse elemento GUI.
Abra o StatusDisplay e defina as seguintes variáveis para o seguir:
Serviço de armazenamento replicado
Pasta DisplayValues
Valor de Status
TextLabel - use script.Parent.
local ReplicatedStorage = game:GetService("ReplicatedStorage")local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")local status = displayValues:WaitForChild("Status")local textLabel = script.Parent
Mudando a Etiqueta de Texto
Para alterar o texto na etiqueta / rótulo, use um evento alterado para que, sempre que a string Status for alterada por outro script, a etiqueta de texto seja atualizada.
Código uma nova função chamada updateText() . Nesta função, configure a propriedade de texto de textLabel para status.Value .
local textLabel = script.Parentlocal function updateText()textLabel.Text = status.ValueendConecte a função ao evento Alterado.
local function updateText()textLabel.Text = status.Valueendstatus.Changed:Connect(updateText)Para que os jogadores vejam o status mais recente quando iniciar o jogo, execute updateText() no final do script.
local function updateText()textLabel.Text = status.Valueendstatus.Changed:Connect(updateText)updateText()Execute o jogo e confirme que você vê o valor temporário na exibição.
Criando o Gerenciador de Exibição
Durante um jogo, a etiqueta de texto precisará obter informações do GameManager, MatchManager e, possivelmente, de outros scripts. Para que esses diferentes scripts possam atualizar a etiqueta de texto quando necessário, crie um script de módulo chamado DisplayManager.
Configurando o Script
Como o DisplayManager precisa se comunicar com outros scripts, será um script de módulo.
Em ServerStorage > ModuleScripts , crie um novo script de módulo chamado DisplayManager. Renomeie a tabela de módulo para corresponder ao nome do script.
Adicionar variáveis locais para o seguindo: Replicated Storage, DisplayValues pasta, Status.
local DisplayManager = {}-- Serviçoslocal ReplicatedStorage = game:GetService("ReplicatedStorage")-- Exibir Valores usados para atualizar a Interface gráfica do usuáriodo Jogadorlocal displayValues = ReplicatedStorage:WaitForChild("DisplayValues")local status = displayValues:WaitForChild("Status")-- Funções Locais-- Funções de Moduloreturn DisplayManagerCrie uma nova função de módulo chamada updateStatus() que atualiza a string no valor Status. Outros scripts poderão chamar essa função.
-- Funções Locais-- Funções de Modulofunction DisplayManager.updateStatus(newStatus)status.Value = newStatusend
Atualizando o Status do Texto
Com o Gerenciador de Display configurado, ele pode ser usado em outros scripts para atualizar a etiqueta / rótulode texto GUI. Como a primeira mensagem na Interface gráfica do usuário, mostre o início e o fim da intermissão através do script Gerenciador de Jogo.
In ServerScriptService > GameManager, create a variable named displayManager and require the DisplayManager module in ServerStorage.
-- Serviçoslocal ReplicatedStorage = game:GetService("ReplicatedStorage")local ServerStorage = game:GetService("ServerStorage")local Players = game:GetService("Players")-- Scripts de Módulolocal moduleScripts = ServerStorage:WaitForChild("ModuleScripts")local roundManager = require(moduleScripts:WaitForChild("RoundManager"))local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))Como a primeira linha depois da declaração while true, chame displayManager > updateStatus() e passe em uma mensagem sobre a espera por jogadores.
-- Eventoslocal events = ServerStorage:WaitForChild("Events")local matchEnd = events:WaitForChild("MatchEnd")while true dodisplayManager.updateStatus("Waiting for Players")repeatprint("Starting intermission")task.wait(gameSettings.intermissionDuration)until #Players:GetPlayers() >= gameSettings.minimumPlayerstask.wait(gameSettings.transitionTime)matchManager.prepareGame()matchEnd.Event:Wait()endApós o fim do loop de repetição para a intermissão, chame updateStatus() e passe em uma string anunciando que a partida está começando. Como você estará testando com o Interface gráfica do usuário, exclua as duas declarações de print para notar o começo e o fim da intermissão.
while true dodisplayManager.updateStatus("Waiting for Players")repeattask.wait(gameSettings.intermissionDuration)until #Players:GetPlayers() >= gameSettings.minimumPlayersdisplayManager.updateStatus("Get ready!")task.wait(gameSettings.transitionTime)matchManager.prepareGame()matchEnd.Event:Wait()endTeste o jogo com e sem seus jogadores mínimos. A mensagem deve ler o seguindo:
- Sem os jogadores mínimos: "Waiting for Players" .
- Com os jogadores mínimos: "Get ready".
Dicas de solução de problemas
Neste ponto, se a etiqueta de texto não exibir a primeira mensagem ou ainda exibir "Label", tente um dos seguintes abaixo.
- Certifique-se no script local StatusDisplay que updateText() é chamado na parte inferior do script. Isso garante que o jogador receba a mensagem mais recente.
- Verifique se o Valor de Status está em ReplicatedStorage. Devido à natureza única das relações cliente-servidor, se estiver em ServerStorage, um script local não será capaz de encontrá-lo.
Exibindo Status de Partida
Durante uma conferir, a GUI exibirá dois números: o número de jogadores restantes e o tempo. À medida que esses números mudam, a etiqueta de texto também será alterada.
Configurando Valores e Funções
Os valores Int serão usados para armazenar o número de jogadores e o tempo restante.
Em ReplicatedStorage > DisplayValues, crie dois IntValues chamados PlayersLeft e TimeLeft.
No DisplayManager, adicione variáveis para armazenar os valores esquerdos e de tempo restantes.
local DisplayManager = {}-- Serviçoslocal ReplicatedStorage = game:GetService("ReplicatedStorage")-- Exibir Valores usados para atualizar a Interface gráfica do usuáriodo Jogadorlocal displayValues = ReplicatedStorage:WaitForChild("DisplayValues")local status = displayValues:WaitForChild("Status")local playersLeft = displayValues:WaitForChild("PlayersLeft")local timeLeft = displayValues:WaitForChild("TimeLeft")Crie uma função local chamada updateMatchStatus() . Em seguida, configure o valor do status para exibir o número de jogadores restantes e o tempo restante.
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")local status = displayValues:WaitForChild("Status")local playersLeft = displayValues:WaitForChild("PlayersLeft")local timeLeft = displayValues:WaitForChild("TimeLeft")-- Funções Locaislocal function updateRoundStatus()status.Value = "Players Left: " .. playersLeft.Value .. " / Time Left: " .. timeLeft.ValueendPara ambas as variáveis INTValue , conecte updateRoundStatus() ao evento Alterado.
-- Funções de Modulofunction DisplayManager.updateStatus(newStatus)status.Value = newStatusendplayersLeft.Changed:Connect(updateRoundStatus)timeLeft.Changed:Connect(updateRoundStatus)return DisplayManager
Exibindo Jogadores
Em seguida, adicione o código para exibir o número de jogadores no início de um jogo. As aulas posteriores atualizarão o valor PlayersLeft à medida que os jogadores são eliminados do jogo.
In PlayerManager, adicione variáveis locais para o serviço ReplicatedStorage, pasta DisplayValues e PlayersLeft IntValue.
local PlayerManager = {}-- Serviçoslocal Players = game:GetService("Players")local ServerStorage = game:GetService("ServerStorage")local ReplicatedStorage = game:GetService("ReplicatedStorage")-- Variáveis de Mapalocal lobbySpawn = workspace.Lobby.StartSpawnlocal arenaMap = workspace.Arenalocal spawnLocations = arenaMap.SpawnLocations-- Valoreslocal displayValues = ReplicatedStorage:WaitForChild("DisplayValues")local playersLeft = displayValues:WaitForChild("PlayersLeft")Mostre o número inicial de jogadores ao definir o valor de playersLeft para o tamanho da matriz / listade jogadores ativos.
Então, em sendPlayersToMatch() , sob o for loop, digitar: playersLeft.Value = #activePlayers
function PlayerManager.sendPlayersToMatch()local availableSpawnPoints = spawnLocations:GetChildren()for playerKey, whichPlayer in Players:GetPlayers() dotable.insert(activePlayers, whichPlayer)local spawnLocation = table.remove(availableSpawnPoints, 1)preparePlayer(whichPlayer, spawnLocation)endplayersLeft.Value = #activePlayersend
Exibindo o Temporizador
Lembre-se de que scripts de módulo são usados para centralizar código semelhante. Como o tempo é rastreado no MatchManager, atualize o valor TimeLeft usando funções do script Timer. O gerenciador de exibição ouvirá alterações no TimeLeft e atualizará para corresponder ao novo valor.
In MatchManager, crie variáveis para armazenar o serviço Armazenamento Replicado , o diretório DisplayColors e o valor TimeLeft.
local MatchManager = {}-- Serviçoslocal ServerStorage = game:GetService("ServerStorage")local ReplicatedStorage = game:GetService("ReplicatedStorage")-- Scripts de Módulolocal moduleScripts = ServerStorage:WaitForChild("ModuleScripts")local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))local timer = require(moduleScripts:WaitForChild("Timer"))-- Eventoslocal events = ServerStorage:WaitForChild("Events")local matchStart = events:WaitForChild("MatchStart")-- Valoreslocal displayValues = ReplicatedStorage:WaitForChild("DisplayValues")local timeLeft = displayValues:WaitForChild("TimeLeft")local myTimer = timer.new()Encontre a função startTimer(). Depois do evento Finished do timer, copie e cole todo o evento Finished abaixo. O código executa um loop para atualizar o valor 1> timeLeft1> enquanto o timer ainda está ativo.
while myTimer:isRunning() do-- Adicionar +1 garante que o display do timer termine em 1 em vez de 0.timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))-- Ao não definir o tempo para esperar, ele oferece mais precisão de loopingtask.wait()endQuando adicionado, o código deve ser semelhante ao exemplo abaixo.
local function startTimer()print("Timer started")myTimer:start(gameSettings.matchDuration)myTimer.finished:Connect(timeUp)while myTimer:isRunning() do-- Adicionar +1 garante que o display do timer termine em 1 em vez de 0.timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))-- Ao não definir o tempo para esperar, ele oferece mais precisão de loopingtask.wait()endendExecute o jogo com os jogadores mínimos. Verifique se o texto de status é exibido:
- A quantidade correta de jogadores de partida iniciais. Lembre-se, esse número não vai mudar até que mais código seja adicionado em uma futura lição.
- O tempo diminui a cada segundo até chegar em 1.
Scripts Concluídos
Abaixo estão scripts concluídos para verificar duas vezes seu trabalho.
Script do GameManager
-- Serviçoslocal ServerStorage = game:GetService("ServerStorage")local Players = game:GetService("Players")-- Scripts de Módulolocal moduleScripts = ServerStorage:WaitForChild("ModuleScripts")local matchManager = require(moduleScripts:WaitForChild("MatchManager"))local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))-- Eventoslocal events = ServerStorage:WaitForChild("Events")local matchEnd = events:WaitForChild("MatchEnd")while true dodisplayManager.updateStatus("Waiting for Players")repeattask.wait(gameSettings.intermissionDuration)until #Players:GetPlayers() >= gameSettings.minimumPlayersdisplayManager.updateStatus("Get ready!")task.wait(gameSettings.transitionTime)matchManager.prepareGame()matchEnd.Event:Wait()end
Script do Gerenciador de Exibição
local DisplayManager = {}
-- Serviços
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Exibir Valores usados para atualizar a Interface gráfica do usuáriodo Jogador
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local status = displayValues:WaitForChild("Status")
local playersLeft = displayValues:WaitForChild("PlayersLeft")
local timeLeft = displayValues:WaitForChild("TimeLeft")
-- Funções Locais
local function updateRoundStatus()
status.Value = "Players Left: " .. playersLeft.Value .. " / Time Left: " .. timeLeft.Value
end
-- Funções de Modulo
function DisplayManager.updateStatus(newStatus)
status.Value = newStatus
end
playersLeft.Changed:Connect(updateRoundStatus)
timeLeft.Changed:Connect(updateRoundStatus)
return DisplayManager
Script do MatchManager
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Scripts de Módulo
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local timer = require(moduleScripts:WaitForChild("Timer"))
-- Eventos
local events = ServerStorage:WaitForChild("Events")
local matchStart = events:WaitForChild("MatchStart")
local matchEnd = events:WaitForChild("MatchEnd")
-- Valores
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local timeLeft = displayValues:WaitForChild("TimeLeft")
local myTimer = timer.new()
-- Funções Locais
local function timeUp()
print("Time is up!")
end
local function startTimer()
print("Timer started")
myTimer:start(gameSettings.matchDuration)
myTimer.finished:Connect(timeUp)
while myTimer:isRunning() do
-- Adicionar +1 garante que o display do timer termine em 1 em vez de 0.
timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))
-- Ao não definir o tempo para esperar, ele oferece mais precisão de looping
task.wait()
end
end
-- Funções de Modulo
function MatchManager.prepareGame()
playerManager.sendPlayersToMatch()
matchStart:Fire()
end
matchStart.Event:Connect(startTimer)
return MatchManager
Exibir Status
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local status = displayValues:WaitForChild("Status")
local textLabel = script.Parent
local function updateText()
textLabel.Text = status.Value
end
status.Changed:Connect(updateText)
updateText()