Obecnie większość informacji o grze znajduje się w oknie wyjściowym, niewidocznym dla graczy. Więc gracze mogą być informowani o tym, co dzieje się w grze, tworząc interfejs użytkownika graficznego (GUI) i kodując go.
Pokazywanie informacji za pomocą interfejsu użytkownika
Dla tej gry w okienku tekstowym wyświetlony zostanie bieżący stan gry, a także pozostała liczba graczy i czas.
Ustawienie GUI
Najpierw stwórz obiekt GUI ekranu , aby pomieścić różne elementy tekstu. Gdy gracz porusza kamerę, ekran GUI pozostaje w tym samym miejscu na ekranie.
Aby upewnić się, że wszyscy gracze zobaczą ten sam wygląd, umieść GUI w StarterGui katalogu. Podczas uruchomienia gry ten katalog jest kopiowany do wszystkich graczy.
W katalogu StarterGui utwórz nowy ScreenGUI. Następnie w ScreenGUI dodaj nowy TextLabel nazyający się StatusText.
Aby przenieść etykietę, w Explorerze, wybierz StatusText. Następnie w widoku gry przeciągnij etykietę, gdzie chcesz, aby się znajdowała. Twoje liczby mogą się różnić od wideo. Label można również skalować używając kątów ankora na kątach.
Skryptowanie interfejsu
Aby odzwierciedlić zmiany w gra, skrypty będą musiały aktualizować elementy GUI. Na instancja, status gry, czy to przerwa czy runda aktywna, będzie zapisany w zmiennej StringsValue i zostanie zaktualizowany za pomocą lokalnych skryptów.
Konfiguracja Skryptu
Skrypt StatusDisplay zostanie użyty do aktualizacji interfejsu gracza, gdy stan gry się zmieni.
W ReplicatedStorage , utwórz katalog o nazwie DisplayValues. W tym katalogu dodaj strungową wartość nazyającą się Status. Aby testować wartość później, dodaj tymczasową wartość, taką jak "Witaj w bitwie!".
W StarterGui > ScreenGUI > Status, dodaj nowy lokalny skrypt nazyający się StatusDisplay. Skrypty, które wpływają na GUI, są często powiązane z tym elementem GUI.
Otwórz StatusDisplay i zdefiniuj następujące zmienne dla obserwowaćfunkcji:
Usługa ReplicatedStorage
Katalog Display Values
Wartość statusu
TextLabel - użyj script.Parent.
local ReplicatedStorage = game:GetService("ReplicatedStorage")local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")local status = displayValues:WaitForChild("Status")local textLabel = script.Parent
Zmiana tekstowej etykiety
Aby zmienić tekst w etykiecie użyj zmienionego wydarzenia, aby zawsze, gdy stan będzie zmieniony przez inny skrypt, tekst w polu label zostanie zaktualizowany.
Zakoduj nową funkcję o nazwie updateText() . W tej funkcji ustaw właściwość tekstu textLabel na status.Value .
local textLabel = script.Parentlocal function updateText()textLabel.Text = status.ValueendPołącz funkcję z wydarzeniem Zmienionym.
local function updateText()textLabel.Text = status.Valueendstatus.Changed:Connect(updateText)Aby gracze mogli zobaczyć najnowszy stan bieżącego przy statusie, kiedy rozpoczynają grę, zakończ updateText() na końcu skryptu.
local function updateText()textLabel.Text = status.Valueendstatus.Changed:Connect(updateText)updateText()Zacznij grę i potwierdź, że widzisz tymczasową wartość w wyświetlaniu.
Tworzenie Menadżera Wyświetlania
Podczas graw etykietę tekstową będzie musiała uzyskać informacje od GameManager, MatchManager i ewentualnie innych skryptów. W ten sposób te różne skrypty mogą aktualizować tekstową etykietę, gdy będzie to konieczne, tworzyć modułowy skrypt nazyający się DisplayManager.
Konfiguracja Skryptu
Ponieważ DisplayManager musi komunikować się z innymi skryptami, będzie to modułowy skrypt.
W ServerStorage > ModuleScripts , utwórz nowy skrypt modułowy nazyający się DisplayManager. Zmień tabelę modułu, aby odpowiadała imieniu skryptu.
Dodaj lokalne zmienne dla obserwujefunkcjonalności: Replicated Storage, DisplayValues i Status.
local DisplayManager = {}-- Usługilocal ReplicatedStorage = game:GetService("ReplicatedStorage")-- Pokazuj wartości używane do aktualizacji interfejsu graczalocal displayValues = ReplicatedStorage:WaitForChild("DisplayValues")local status = displayValues:WaitForChild("Status")-- Lokalne funkcje-- Funkcje modułureturn DisplayManagerUtwórz nową funkcję modułu nazyającą się updateStatus() która aktualizuje wartość statusu. Inne skrypty będą mogły wezwywać tę funkcję.
-- Lokalne funkcje-- Funkcje modułufunction DisplayManager.updateStatus(newStatus)status.Value = newStatusend
Aktualizowanie stanu tekstu
Z ustawionym Managerem Wyświetlenia można go używać w innych skryptach, aby aktualizować tekst label GUI. Jako pierwszy wiadomość w GUI, pokaż początek i koń przerwy poprzez skrypt GameManager.
W ServerScriptService > GameManager utwórz zmienne nazyjące się displayManager i wymagaj modułu Pokazuj Managera w SerwerStorage.
-- Usługilocal ReplicatedStorage = game:GetService("ReplicatedStorage")local ServerStorage = game:GetService("ServerStorage")local Players = game:GetService("Players")-- Skripty modułulocal moduleScripts = ServerStorage:WaitForChild("ModuleScripts")local roundManager = require(moduleScripts:WaitForChild("RoundManager"))local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))Jako pierwsza linia po stwierdzenie prawdy, wezwij displayManager > updateStatus() i przekaż wiadomość o czekaniu na graczy.
-- Wydarzenialocal 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()endPo zakończeniu pętli powtarzającej się dla przerwy, wezwij updateStatus() i przekaż w ciągu zmiany strumieni informującą o rozpoczęciu i zakończeniu przerwy. Ponieważ będziesz testować z GUI, usuń dwa stwierdzające początek i koń przerwy znaczniki.
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()endTestuj grę z i bez swoich minimalnych graczy. Wiadomość powinna czytać obserwuje:
- Bez minimum graczy: "Waiting for Players" .
- Z minimalną liczbą graczy: "Get ready" .
Wskazówki dotyczące rozwiązywania problemów
W tym momencie, jeśli etykieta tekstowa nie wyświetla pierwszej wiadomość, lub nadal wyświetla "Label", spróbuj jednej z poniższych opcji poniżej.
- Upewnij się, że w lokalnym skrypcie StatusDisplay updateText() jest wezwany na dole skryptu. Dzięki temu upewniasz się, że gracz otrzymuje najnowszą wiadomość.
- Sprawdź, czy wartość statusu jest w ReplicatedStorage. Ze względu na unikalną naturę stosunków klienta-serwera, jeśli jest ona w ServerStorage, lokalny skrypt nie będzie w stanie jej znaleźć.
Pokazywanie stanu bicia
Podczas dopasowywaćGUI wyświetli dwa liczby: pozostałą liczbę graczy i czas. W miarę, jak te liczby się zmieniają, tekstowa etykieta zmieni się również.
Ustawianie wartości i funkcji
IntViews będzie używany do przechowywania liczby graczy i czasu pozostałego.
W ReplicatedStorage > DisplayValues utwórz dwa IntViews nazyające się PlayersLeft i TimeLeft.
W DisplayManager dodaj zmienne, aby przechować pozostałe wartości i czas pozostały w grze.
local DisplayManager = {}-- Usługilocal ReplicatedStorage = game:GetService("ReplicatedStorage")-- Pokazuj wartości używane do aktualizacji interfejsu graczalocal displayValues = ReplicatedStorage:WaitForChild("DisplayValues")local status = displayValues:WaitForChild("Status")local playersLeft = displayValues:WaitForChild("PlayersLeft")local timeLeft = displayValues:WaitForChild("TimeLeft")Utwórz lokalną funkcję nazyającą się updateMatchStatus() . Następnie ustaw wartość statusu, aby wyświetlić liczbę pozostałych graczy i czas pozostały.
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")local status = displayValues:WaitForChild("Status")local playersLeft = displayValues:WaitForChild("PlayersLeft")local timeLeft = displayValues:WaitForChild("TimeLeft")-- Lokalne funkcjelocal function updateRoundStatus()status.Value = "Players Left: " .. playersLeft.Value .. " / Time Left: " .. timeLeft.ValueendDla obu zmiannych zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian zmian
-- Funkcje modułufunction DisplayManager.updateStatus(newStatus)status.Value = newStatusendplayersLeft.Changed:Connect(updateRoundStatus)timeLeft.Changed:Connect(updateRoundStatus)return DisplayManager
Pokazywanie graczy
Następnie dodaj kod do wyświetlenia liczby graczy na początku gry. Późniejsze lekcje będą aktualizować wartość PlayersLeft, gdy gracze są wyeliminowani z gry.
W PlayerManager dodaj lokalne zmienne dla usługi ReplicatedStorage, katalogu DisplayValues i PlayersLeft IntValue.
local PlayerManager = {}-- Usługilocal Players = game:GetService("Players")local ServerStorage = game:GetService("ServerStorage")local ReplicatedStorage = game:GetService("ReplicatedStorage")-- Zróżnicowane Mapylocal lobbySpawn = workspace.Lobby.StartSpawnlocal arenaMap = workspace.Arenalocal spawnLocations = arenaMap.SpawnLocations-- Wartościlocal displayValues = ReplicatedStorage:WaitForChild("DisplayValues")local playersLeft = displayValues:WaitForChild("PlayersLeft")Pokaż liczbę początkowych graczy, ustawiając wartość playersLeft do rozmiaru aktywnej listy graczy.
Następnie, w sendPlayersToMatch() , pod warunkiem pętli, wpisywać: 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
Pokazywanie licznika
Pamiętaj, że skrypcje modułu są używane do centralizacji podobnego kodu. Skoro licznik jest śledzony w MatchManager, aktualizuj wartość TimeLeft używając funkcji ze skryptu Timer. Menadżer wyświetlenia będzie słuchać zmian w TimeLeft i aktualizować je do zgadzenia nowej wartości.
W MatchManagerze twórz zmienne, aby ReplicatedStorage usługa, katalog DisplayColors i TimeLeft.
local MatchManager = {}-- Usługilocal ServerStorage = game:GetService("ServerStorage")local ReplicatedStorage = game:GetService("ReplicatedStorage")-- Skripty modułulocal moduleScripts = ServerStorage:WaitForChild("ModuleScripts")local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))local timer = require(moduleScripts:WaitForChild("Timer"))-- Wydarzenialocal events = ServerStorage:WaitForChild("Events")local matchStart = events:WaitForChild("MatchStart")-- Wartościlocal displayValues = ReplicatedStorage:WaitForChild("DisplayValues")local timeLeft = displayValues:WaitForChild("TimeLeft")local myTimer = timer.new()Znajdź funkcję startTimer(). Po wydarzeniu czasu Finished zegara, skopiuj i wklej całą, zaznaconą poniżej, pizzę. Kod wykonuje pętę, aby aktualizować wartość 1> timeLeft1> dalej, dopóki zegar jest jeszcze aktywny.
while myTimer:isRunning() do-- Dodanie +1 upewnia się, że ekran zlicznika kończy się na 1, a nie na 0.timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))-- Nie ustawiając czasu na czekanie, oferuje ono bardziej dokładne pętlenietask.wait()endKiedy zostanie dodany, kod powinien wyglądać jak przykład poniżej.
local function startTimer()print("Timer started")myTimer:start(gameSettings.matchDuration)myTimer.finished:Connect(timeUp)while myTimer:isRunning() do-- Dodanie +1 upewnia się, że ekran zlicznika kończy się na 1, a nie na 0.timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))-- Nie ustawiając czasu na czekanie, oferuje ono bardziej dokładne pętlenietask.wait()endendZacznij grę z najniższymi graczami. Sprawdź, czy tekst statusowy się wyświetla:
- Poprawna liczba początkowych graczy. Pamiętaj, że ta liczba nie będzie się zmieniać, dopóki dodatkowy kod nie zostanie dodany w przyszłej lekcji.
- Czas zmniejsza się co 1 sekundę, aż do 1.
Ukończone Skrypcity
Poniżej znajdują się zakończone skrypty, aby podwoić sprawdzenie swojej pracy.
Skrypt GameManager
-- Usługilocal ServerStorage = game:GetService("ServerStorage")local Players = game:GetService("Players")-- Skripty modułulocal moduleScripts = ServerStorage:WaitForChild("ModuleScripts")local matchManager = require(moduleScripts:WaitForChild("MatchManager"))local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))-- Wydarzenialocal 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
Skrypt Managera Wyświetlania
local DisplayManager = {}
-- Usługi
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Pokazuj wartości używane do aktualizacji interfejsu gracza
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local status = displayValues:WaitForChild("Status")
local playersLeft = displayValues:WaitForChild("PlayersLeft")
local timeLeft = displayValues:WaitForChild("TimeLeft")
-- Lokalne funkcje
local function updateRoundStatus()
status.Value = "Players Left: " .. playersLeft.Value .. " / Time Left: " .. timeLeft.Value
end
-- Funkcje modułu
function DisplayManager.updateStatus(newStatus)
status.Value = newStatus
end
playersLeft.Changed:Connect(updateRoundStatus)
timeLeft.Changed:Connect(updateRoundStatus)
return DisplayManager
Skrypt MatchManager
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Skripty modułu
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local timer = require(moduleScripts:WaitForChild("Timer"))
-- Wydarzenia
local events = ServerStorage:WaitForChild("Events")
local matchStart = events:WaitForChild("MatchStart")
local matchEnd = events:WaitForChild("MatchEnd")
-- Wartości
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local timeLeft = displayValues:WaitForChild("TimeLeft")
local myTimer = timer.new()
-- Lokalne funkcje
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
-- Dodanie +1 upewnia się, że ekran zlicznika kończy się na 1, a nie na 0.
timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))
-- Nie ustawiając czasu na czekanie, oferuje ono bardziej dokładne pętlenie
task.wait()
end
end
-- Funkcje modułu
function MatchManager.prepareGame()
playerManager.sendPlayersToMatch()
matchStart:Fire()
end
matchStart.Event:Connect(startTimer)
return MatchManager
Skrypt StatusDisplay
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()