No momento, grande parte das informações do jogo está atualmente na Janela de Saída, invisível para os jogadores. Para que os jogadores possam ser informados do que está acontecendo no jogo, você criará uma interface de usuário gráfica (Interface gráfica do usuário) e a codificará.
Para este jogo, um rótulo de texto exibirá o status do jogo atual, bem como o número e o tempo de jogadores restantes.
Configurando a Interface gráfica do usuário
Primeiro, crie um objeto Screen GUI para conter os diferentes elementos de texto. Quando o jogador move a Câmera, a GUI da tela permanece no mesmo lugar em sua tela.
Para garantir que todos os jogadores vejam a mesma tela, coloque a GUI na pasta StarterGUI . Na inicialização do jogo, essa pasta é copiada para todos os jogadores.
Na pasta StarterGUI, crie uma nova ScreenGUI. Em seguida, na ScreenGUI, adicione uma nova etiqueta de texto chamada StatusText.
Para mover o etiqueta / rótulo, no Explorador, selecione StatusText. Em seguida, na exibição do jogo, arraste o rótulo para onde você gostaria. Seus números podem diferir do vídeo. O rótulo também pode ser redimensionado usando os pontos de ancoragem nos cantos.
Programando a Interface gráfica do usuário
Para refletir as mudanças no jogo, os scripts precisarão atualizar os elementos GUI. Por instância, o status do jogo, seja um intervalo ou uma rodada ativa, será armazenado em um StringValue e atualizado usando scripts locais.
Em comparação com scripts e scripts de módulos que rodam servidores Roblox, scripts locais rodam no dispositivo de um jogador. Eles são frequentemente usados para codificar elementos GUI, como a entrada do temporizador ou do jogador, como ações do mouse ou do teclado.
Configurando o Script
O script StatusDisplay será usado para atualizar a GUI do jogador sempre que o estado do jogo mudar.
Em ReplicatedStorage , crie uma pasta chamada DisplayValues. Nessa pasta, adicione um StringValue chamado Status. Para testar o valor mais tarde, dê a ele um valor temporário, como "Bem-vindo à Batalha!"
Como os scripts locais só são rodados no dispositivo de um jogador, eles não podem ser armazenados em pastas do servidor, como o ServerStorage. ReplicatedStorage é uma pasta disponível tanto para o cliente (dispositivo) quanto para o servidor.
Em StarterGUI > ScreenGUI > Status, adicione um novo script local chamado StatusDisplay. Scripts que afetam a GUI são frequentemente parentalizados a esse elemento GUI.
Abra StatusDisplay e defina as seguintes variáveis para o seguir:
Serviço de armazenamento replicado
Pasta DisplayValues
Status StringValue
Etiqueta de Texto - use script.Parent
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local status = displayValues:WaitForChild("Status")
local textLabel = script.Parent
Mudando o rótulo de texto
Para alterar o texto no etiqueta / rótulo, use um evento Modificado para que sempre que a string de Status for alterada por outro script, o rótulo de texto seja atualizado.
Crie uma nova função chamada updateText(). Nessa função, defina a propriedade Text de textLabel para status.Value.
local textLabel = script.Parent
local function updateText()
textLabel.Text = status.Value
end
Conecte a função ao evento Modificado.
local function updateText()
textLabel.Text = status.Value
end
status.Changed:Connect(updateText)
Para que os jogadores vejam o status mais atualizado ao iniciar o jogo, corra updateText() no final do script.
local function updateText()
textLabel.Text = status.Value
end
status.Changed:Connect(updateText)
updateText()
Inicie o jogo e confirme que você vê o valor temporário na tela.
Criando o Gerenciador de Display
Durante um jogo, a etiqueta de texto precisará obter informações do GameManager, MatchManager e, possivelmente, de outros scripts. Para que esses scripts diferentes 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ódulos para combinar com o nome do script.
Adicione variáveis locais para o seguindo: Replicated Storage, DisplayValues folder, Status.
local DisplayManager = {}
-- Serviços
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Valores de exibição usados para atualizar a Interface gráfica do usuáriodo jogador
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local status = displayValues:WaitForChild("Status")
-- Funções Locais
-- Funções do módulo
return DisplayManager
Crie uma nova função de módulo chamada updateStatus() que atualize a string no valor Status. Outros scripts poderão chamar essa função.
-- Funções Locais
-- Funções do módulo
function DisplayManager.updateStatus(newStatus)
status.Value = newStatus
end
Atualizando o Status do Texto
Com o Gerenciador de Exibição configurado, ele pode ser usado em outros scripts para atualizar o etiqueta / rótulode texto da GUI. Como primeira mensagem na Interface gráfica do usuário, mostre o começo e o fim da interrupção através do script GameManager.
Em ServerScriptService > GameManager, crie uma variável chamada displayManager e exija o módulo DisplayManager no ServerStorage.
-- Serviços
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
-- Scripts de Módulo
local 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 após a declaração while true do, chame displayManager > updateStatus() e passe em uma mensagem sobre esperar por jogadores.
-- Eventos
local events = ServerStorage:WaitForChild("Events")
local matchEnd = events:WaitForChild("MatchEnd")
while true do
displayManager.updateStatus("Waiting for Players")
repeat
print("Starting intermission")
task.wait(gameSettings.intermissionDuration)
until #Players:GetPlayers() >= gameSettings.minimumPlayers
task.wait(gameSettings.transitionTime)
matchManager.prepareGame()
matchEnd.Event:Wait()
end
Após o final do loop de repetição para o intervalo, chame updateStatus() e passe em uma string anunciando que a partida está começando. Como você estará testando com a Interface gráfica do usuário, exclua as duas declarações de impressão para anotar o início e o fim do intervalo.
while true do
displayManager.updateStatus("Waiting for Players")
repeat
task.wait(gameSettings.intermissionDuration)
until #Players:GetPlayers() >= gameSettings.minimumPlayers
displayManager.updateStatus("Get ready!")
task.wait(gameSettings.transitionTime)
matchManager.prepareGame()
matchEnd.Event:Wait()
end
Teste o jogo com e sem seus jogadores mínimos. A mensagem deve ler o seguindo:
Sem o mínimo de jogadores: "Waiting for Players" .
Com o mínimo de jogadores: "Get ready" .
Dicas de solução de problemas
Neste ponto, se o rótulo de texto não exibir a primeira mensagem ou ainda exibir "Etiqueta," tente um dos seguintes procedimentos.
Certifique-se no script local StatusDisplay que updateText() é chamado na parte inferior do script. Isso garante que o jogador receba a mensagem mais atualizada.
Verifique se o Status StringValue está no ReplicatedStorage. Devido à natureza única das relações cliente-servidor, se estiver no ServerStorage, um script local não poderá encontrá-lo.
Exibindo Status da 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, o rótulo de texto também mudará.
Configurando Valores e Funções
IntValues será usado para armazenar a contagem 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 dos jogadores restantes e do tempo restante.
local DisplayManager = {}
-- Serviços
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Valores de exibição 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")
Crie uma função local chamada updateMatchStatus() . Em seguida, defina 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 Locais
local function updateRoundStatus()
status.Value = "Players Left: " .. playersLeft.Value .. " / Time Left: " .. timeLeft.Value
end
Para ambas variáveis IntValue, conecte updateRoundStatus() ao evento Changed.
-- Funções do módulo
function DisplayManager.updateStatus(newStatus)
status.Value = newStatus
end
playersLeft.Changed:Connect(updateRoundStatus)
timeLeft.Changed:Connect(updateRoundStatus)
return DisplayManager
Ainda não teste. Nada atualizou os valores de PlayersLeft ou TimeLeft, então o status não será alterado uma vez que uma rodada começar.
Mostrando Jogadores
Em seguida, adicione o código para exibir o número de jogadores no início de um jogo. Lições posteriores atualizarão o valor de PlayersLeft à medida que os jogadores forem eliminados do jogo.
No PlayerManager, adicione variáveis locais para o serviço ReplicatedStorage, pasta DisplayValues e PlayersLeft IntValue.
local PlayerManager = {}
-- Serviços
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Variáveis do Mapa
local lobbySpawn = workspace.Lobby.StartSpawn
local arenaMap = workspace.Arena
local spawnLocations = arenaMap.SpawnLocations
-- Valores
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local playersLeft = displayValues:WaitForChild("PlayersLeft")
Mostra a contagem de jogadores iniciantes definindo o valor de playersLeft para o tamanho da matriz / listade jogadores ativos.
Em seguida, em sendPlayersToMatch() , sob o loop for, digitar: playersLeft.Value = #activePlayers
function PlayerManager.sendPlayersToMatch()
local availableSpawnPoints = spawnLocations:GetChildren()
for playerKey, whichPlayer in Players:GetPlayers() do
table.insert(activePlayers, whichPlayer)
local spawnLocation = table.remove(availableSpawnPoints, 1)
preparePlayer(whichPlayer, spawnLocation)
end
playersLeft.Value = #activePlayers
end
Exibindo o Temporizador
Lembre-se que os scripts de módulo são usados para centralizar código semelhante. Uma vez que o temporizador é rastreado no MatchManager, atualize o valor TimeLeft usando funções do script Timer. O gerenciador de exibição ouvirá as mudanças no TimeLeft e atualizará para corresponder ao novo valor.
No MatchManager, crie variáveis para armazenar o ReplicatedStorage serviço, a pasta DisplayValues e o valor TimeLeft.
local MatchManager = {}
-- Serviços
local ServerStorage = game:GetService("ServerStorage")
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")
-- Valores
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local timeLeft = displayValues:WaitForChild("TimeLeft")
local myTimer = timer.new()
Encontre a função startTimer(). Após o evento Finished do cronômetro, copie e cole o todo, destacado durante o loop abaixo. O código roda um loop para atualizar o valor timeLeft enquanto o cronômetro ainda estiver ativo.
while myTimer:isRunning() do
-- Adicionar +1 garante que a exibição do cronômetro termine em 1 em vez de 0.
timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))
-- Ao não definir o tempo de espera, oferece um loop mais preciso
task.wait()
end
Quando adicionado, o código deve se parecer com o exemplo abaixo.
local function startTimer()
print("Timer started")
myTimer:start(gameSettings.matchDuration)
myTimer.finished:Connect(timeUp)
while myTimer:isRunning() do
-- Adicionar +1 garante que a exibição do cronômetro termine em 1 em vez de 0.
timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))
-- Ao não definir o tempo de espera, oferece um loop mais preciso
task.wait()
end
end
Corra o jogo com o mínimo de jogadores. Verifique se o texto de status é exibido:
A quantidade correta de jogadores iniciantes. Lembre-se, esse número não mudará até que um código adicional seja adicionado em uma lição futura.
O tempo diminui a cada segundo até parar em 1.
Scripts Concluídos
Abaixo estão scripts completos para verificar novamente seu trabalho.
Script do Gerenciador de Jogos
-- Serviços
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
-- Scripts de Módulo
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local matchManager = require(moduleScripts:WaitForChild("MatchManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))
-- Eventos
local events = ServerStorage:WaitForChild("Events")
local matchEnd = events:WaitForChild("MatchEnd")
while true do
displayManager.updateStatus("Waiting for Players")
repeat
task.wait(gameSettings.intermissionDuration)
until #Players:GetPlayers() >= gameSettings.minimumPlayers
displayManager.updateStatus("Get ready!")
task.wait(gameSettings.transitionTime)
matchManager.prepareGame()
matchEnd.Event:Wait()
end
Script do Gerenciador de Display
local DisplayManager = {}
-- Serviços
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Valores de exibição 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 do módulo
function DisplayManager.updateStatus(newStatus)
status.Value = newStatus
end
playersLeft.Changed:Connect(updateRoundStatus)
timeLeft.Changed:Connect(updateRoundStatus)
return DisplayManager
Script do Gerente de Partidas
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 a exibição do cronômetro termine em 1 em vez de 0.
timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))
-- Ao não definir o tempo de espera, oferece um loop mais preciso
task.wait()
end
end
-- Funções do módulo
function MatchManager.prepareGame()
playerManager.sendPlayersToMatch()
matchStart:Fire()
end
matchStart.Event:Connect(startTimer)
return MatchManager
Script de Exibição de 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()