現在,遊戲中的大部分資訊都在輸出視窗中,玩家無法看到。因此,玩家可以被告知遊戲中發生了什麼事情,並且創建一個圖形用戶界面 (GUI) 並將其編寫。
使用 GUI 顯示資訊
對於此遊戲,標籤將顯示當前遊戲狀態以及剩餘玩家數量和時間。
設置使用者GUI
首先,創建一個 屏幕GUI 對象來持有不同的文字元素。當玩家移動相攝影機時,屏幕GUI 會保持在他們的屏幕上。
為確保所有玩家都看到相同的顯示,請將 StarterGui 放置在 StarterGui 夾中。在遊戲啟動時,此夾會對所有玩家複製。
在 StarterGui 夾中,創建一個新的 ScreenGUI。然後在 ScreenGUI 中,添加一個名為 StatusText 的新 TextLabel。
要移動標籤,在 Explorer 中,選擇 StatusText。然後,在遊戲視檢視中,將標籤拖曳到你想要的位置。你的數字可能與視頻不同。標籤也可以使用邊框上的錨點來調整尺寸。
編寫 GUI
要反映遊戲中的變更,請需要更新遊戲中的 GUI 元素。例個體、實例,遊戲狀態、是否為中場休息或啟動回合,都會被存儲在 StringValue 中,並使用本地指令碼更新。
設置指令碼
狀態顯示指令碼將用於更新玩家的 GUI ,當遊戲狀態變更時。
在 ReplicatedStorage 中,建立名為 DisplayValues 的文件夾。在該文件夾中,添加名為 Status 的字串值。要在後端測試值,請在 "歡迎來到戰鬥!" 的暫時值中提供。
在 StarterGui > ScreenGUI > Status 中,添加名為 StatusDisplay 的新本地指令。與 GUI 有關的指令通常會與該 GUI 元素綁定。
開啟狀態顯示,並且定義下列變量:
ReplicatedStorage 服務
DisplayValues 資料欄
狀態字符串值
TextLabel - 使用 script.Parent 。
local ReplicatedStorage = game:GetService("ReplicatedStorage")local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")local status = displayValues:WaitForChild("Status")local textLabel = script.Parent
變更文字標籤
若要變更標籤中的文字,請使用 Changed 事件,因為另一個腳指令碼所訂立的狀態變更時,文字標籤將會更新。
在 updateText() 中命名新功能。在該功能中,將 textLabel 的文字屬性設置為 status.Value。
local textLabel = script.Parentlocal function updateText()textLabel.Text = status.Valueend連接功能到 Changed 事件。
local function updateText()textLabel.Text = status.Valueendstatus.Changed:Connect(updateText)因此玩家在開始遊戲時最新狀態,運行 updateText() 在指令碼結束。
local function updateText()textLabel.Text = status.Valueendstatus.Changed:Connect(updateText)updateText()執行遊戲並確認您在顯示中看到暫時值值。
創建顯示管理器
在遊戲中,文字標籤需要從遊戲管理器、匹配管理器和可能從其他指令碼取得資訊。因此,這些不同的指令碼可以在需要時更新文字標籤,創建名為 DisplayManager 的模組腳本。
設置指令碼
因為 DisplayManager 需要和其他指令碼通訊,所以它會是模組指令碼。
在 ServerStorage > ModuleScripts 中,創建名為 DisplayManager 的新模組脚本。 重命名模組表以符合 script 名稱。
為以追蹤中項目新增本地變量: Replicated Storage、DisplayValues 夾、Status。
local DisplayManager = {}-- 服務local ReplicatedStorage = game:GetService("ReplicatedStorage")-- 顯示使用者介面GUI新的價值local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")local status = displayValues:WaitForChild("Status")-- 本地函數-- 模組功能return DisplayManager建立名為 updateStatus() 的新模組功能,可以更新狀態值中的字串。其他指令碼將能夠呼叫此功能。
-- 本地函數-- 模組功能function DisplayManager.updateStatus(newStatus)status.Value = newStatusend
更新文字狀態
設定顯示管理器後,可以在其他指令碼中使用更新 GUI 標籤。作為 GUI 的第一個訊息,顯示遊戲管理器指令碼的開始和結束。
在 ServerScriptService > GameManager 中,創建一個名為 displayManager 的變數,並且在 ServerStorage 中需要顯示管理器模組。
-- 服務local ReplicatedStorage = game:GetService("ReplicatedStorage")local ServerStorage = game:GetService("ServerStorage")local Players = game:GetService("Players")-- 模組指令碼local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")local roundManager = require(moduleScripts:WaitForChild("RoundManager"))local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))在 while 真 do 句後的第一行, 第一個 行, updateStatus() 並在一個訊息上等待玩家。
-- 事件local 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()end在中場休息結束後,請呼叫 updateStatus() 並使用字串宣佈比賽即將開始。因為你會在 GUI 上測試,因此刪除兩個列印語式以記錄比賽開始和結束。
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使用 與 和 無 你的最低玩家。訊息應該閱讀以追蹤中內容:
- 沒有最低玩家:"Waiting for Players"。
- 使用最小玩家:"Get ready"。
排障提示
如果標籤沒有顯示第一個訊息,或仍然顯示 "Label",請從以下列中嘗試。
- 確認 updateText() 中的 updateText 在指令碼底部。這樣玩家就會得到最新的訊息。
- 檢查StatusStringValue是否存在在ReplicatedStorage中。由於客戶端-伺服器關係的獨特性,如果它在ServerStorage中,本地指令碼將無法找到它。
顯示觀看狀態
在比相符中,GUI 會顯示兩個數字:剩餘玩家數量和時間。當這些數字變化時,文字標籤也會變更。
設定值和函數
IntValues 會用來存儲玩家數量和剩餘時間。
在 ReplicatedStorage > DisplayValues 中,創建兩個名為 PlayersLeft 和 TimeLeft 的 IntValue。
在 DisplayManager 中,增加變數來儲存剩餘玩家和剩餘時間值。
local DisplayManager = {}-- 服務local ReplicatedStorage = game:GetService("ReplicatedStorage")-- 顯示使用者介面GUI新的價值local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")local status = displayValues:WaitForChild("Status")local playersLeft = displayValues:WaitForChild("PlayersLeft")local timeLeft = displayValues:WaitForChild("TimeLeft")創建名為 updateMatchStatus() 的本地函數。然後,將狀態值設置為顯示剩餘時間和玩家數量。
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")local status = displayValues:WaitForChild("Status")local playersLeft = displayValues:WaitForChild("PlayersLeft")local timeLeft = displayValues:WaitForChild("TimeLeft")-- 本地函數local function updateRoundStatus()status.Value = "Players Left: " .. playersLeft.Value .. " / Time Left: " .. timeLeft.Valueend對於 both IntValue 變量,連接 updateRoundStatus() 至 Changed 事件。
-- 模組功能function DisplayManager.updateStatus(newStatus)status.Value = newStatusendplayersLeft.Changed:Connect(updateRoundStatus)timeLeft.Changed:Connect(updateRoundStatus)return DisplayManager
顯示玩家
接下來,添加顯示遊戲開始時玩家數量的代碼。後續的課程將更新玩家Left值,玩家被淘汰時從遊戲中更新。
在 PlayerManager 中,為 ReplicatedStorage 服務、DisplayValues 夾和 PlayersLeft IntValue 增加本地變量。
local PlayerManager = {}-- 服務local Players = game:GetService("Players")local ServerStorage = game:GetService("ServerStorage")local ReplicatedStorage = game:GetService("ReplicatedStorage")-- 地圖變量local lobbySpawn = workspace.Lobby.StartSpawnlocal arenaMap = workspace.Arenalocal spawnLocations = arenaMap.SpawnLocations-- 值local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")local playersLeft = displayValues:WaitForChild("PlayersLeft")將 playersLeft 的值設為 playersLeft 的大小來顯示開始玩家陣列量。
然後,在 sendPlayersToMatch() 的 for 回合中,輸入型 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
顯示計時器
記住模組指令碼是用來中央化相同的代碼。因為 Timer 會在 MatchManager 中追蹤時間,所以使用 Timer 指令碼的函數更新 TimeLeft 值。顯示管理器會偵測到 TimeLeft 的變更,並且更新以符合新值。
在 MatchManager 中,創建變數來存儲 ReplicatedStorage 服務、DisplayValues 夾和 TimeLeft 值。
local MatchManager = {}-- 服務local ServerStorage = game:GetService("ServerStorage")local ReplicatedStorage = game:GetService("ReplicatedStorage")-- 模組指令碼local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))local timer = require(moduleScripts:WaitForChild("Timer"))-- 事件local events = ServerStorage:WaitForChild("Events")local matchStart = events:WaitForChild("MatchStart")-- 值local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")local timeLeft = displayValues:WaitForChild("TimeLeft")local myTimer = timer.new()找到 startTimer() 函數。 在 計時器的 Finished 事件後,複製並貼在下面的代碼。代碼會執行一個 1>timeLeft1> 值,直到計時器還在啟用時。
while myTimer:isRunning() do-- 將 +1 添加到螢幕的計時器顯示為 1 而不是 0。timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))-- 通過未設定等待時間,它提供更準確的重複task.wait()end添加時,代碼應該看起來像下面的範例。
local function startTimer()print("Timer started")myTimer:start(gameSettings.matchDuration)myTimer.finished:Connect(timeUp)while myTimer:isRunning() do-- 將 +1 添加到螢幕的計時器顯示為 1 而不是 0。timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))-- 通過未設定等待時間,它提供更準確的重複task.wait()endend使用最小玩家執行遊戲。檢查狀態文本是否顯示:
- 正確的開始玩家數量。請記住,此數字在未來的課程中才會變更。
- 時間會每秒鐘減少,直到它停止在 1。
已完成的指令碼
下面是完成審核您的工作的指令碼。
GameManager 指令碼
-- 服務local ServerStorage = game:GetService("ServerStorage")local Players = game:GetService("Players")-- 模組指令碼local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")local matchManager = require(moduleScripts:WaitForChild("MatchManager"))local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))-- 事件local 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
DisplayManager 指令碼
local DisplayManager = {}
-- 服務
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- 顯示使用者介面GUI新的價值
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local status = displayValues:WaitForChild("Status")
local playersLeft = displayValues:WaitForChild("PlayersLeft")
local timeLeft = displayValues:WaitForChild("TimeLeft")
-- 本地函數
local function updateRoundStatus()
status.Value = "Players Left: " .. playersLeft.Value .. " / Time Left: " .. timeLeft.Value
end
-- 模組功能
function DisplayManager.updateStatus(newStatus)
status.Value = newStatus
end
playersLeft.Changed:Connect(updateRoundStatus)
timeLeft.Changed:Connect(updateRoundStatus)
return DisplayManager
MatchManager 指令碼
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- 模組指令碼
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local timer = require(moduleScripts:WaitForChild("Timer"))
-- 事件
local events = ServerStorage:WaitForChild("Events")
local matchStart = events:WaitForChild("MatchStart")
local matchEnd = events:WaitForChild("MatchEnd")
-- 值
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local timeLeft = displayValues:WaitForChild("TimeLeft")
local myTimer = timer.new()
-- 本地函數
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
-- 將 +1 添加到螢幕的計時器顯示為 1 而不是 0。
timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))
-- 通過未設定等待時間,它提供更準確的重複
task.wait()
end
end
-- 模組功能
function MatchManager.prepareGame()
playerManager.sendPlayersToMatch()
matchStart:Fire()
end
matchStart.Event:Connect(startTimer)
return MatchManager
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()