創建一個 GUI

*此內容是使用 AI(Beta 測試版)翻譯,可能含有錯誤。若要以英文檢視此頁面,請按一下這裡

現在,遊戲中的大部分資訊都在輸出視窗中,玩家無法看到。因此,玩家可以被告知遊戲中發生了什麼事情,並且創建一個圖形用戶界面 (GUI) 並將其編寫。

使用 GUI 顯示資訊

對於此遊戲,標籤將顯示當前遊戲狀態以及剩餘玩家數量和時間。

中場休息期間
在比賽期間

設置使用者GUI

首先,創建一個 屏幕GUI 對象來持有不同的文字元素。當玩家移動相攝影機時,屏幕GUI 會保持在他們的屏幕上。

為確保所有玩家都看到相同的顯示,請將 StarterGui 放置在 StarterGui 夾中。在遊戲啟動時,此夾會對所有玩家複製。

  1. 在 StarterGui 夾中,創建一個新的 ScreenGUI。然後在 ScreenGUI 中,添加一個名為 StatusText 的新 TextLabel。

  2. 要移動標籤,在 Explorer 中,選擇 StatusText。然後,在遊戲視檢視中,將標籤拖曳到你想要的位置。你的數字可能與視頻不同。標籤也可以使用邊框上的錨點來調整尺寸。

編寫 GUI

要反映遊戲中的變更,請需要更新遊戲中的 GUI 元素。例個體、實例,遊戲狀態、是否為中場休息或啟動回合,都會被存儲在 StringValue 中,並使用本地指令碼更新。

設置指令碼

狀態顯示指令碼將用於更新玩家的 GUI ,當遊戲狀態變更時。

  1. ReplicatedStorage 中,建立名為 DisplayValues 的文件夾。在該文件夾中,添加名為 Status 的字串值。要在後端測試值,請在 "歡迎來到戰鬥!" 的暫時值中提供。

  2. 在 StarterGui > ScreenGUI > Status 中,添加名為 StatusDisplay 的新本地指令。與 GUI 有關的指令通常會與該 GUI 元素綁定。

  3. 開啟狀態顯示,並且定義下列變量:

    • 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 事件,因為另一個腳指令碼所訂立的狀態變更時,文字標籤將會更新。

  1. updateText() 中命名新功能。在該功能中,將 textLabel 的文字屬性設置為 status.Value


    local textLabel = script.Parent
    local function updateText()
    textLabel.Text = status.Value
    end
  2. 連接功能到 Changed 事件。


    local function updateText()
    textLabel.Text = status.Value
    end
    status.Changed:Connect(updateText)
  3. 因此玩家在開始遊戲時最新狀態,運行 updateText() 在指令碼結束。


    local function updateText()
    textLabel.Text = status.Value
    end
    status.Changed:Connect(updateText)
    updateText()
  4. 執行遊戲並確認您在顯示中看到暫時值值。

創建顯示管理器

在遊戲中,文字標籤需要從遊戲管理器、匹配管理器和可能從其他指令碼取得資訊。因此,這些不同的指令碼可以在需要時更新文字標籤,創建名為 DisplayManager 的模組腳本。

設置指令碼

因為 DisplayManager 需要和其他指令碼通訊,所以它會是模組指令碼。

  1. ServerStorage > ModuleScripts 中,創建名為 DisplayManager 的新模組脚本。 重命名模組表以符合 script 名稱。

  2. 為以追蹤中項目新增本地變量: Replicated Storage、DisplayValues 夾、Status。


    local DisplayManager = {}
    -- 服務
    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    -- 顯示使用者介面GUI新的價值
    local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
    local status = displayValues:WaitForChild("Status")
    -- 本地函數
    -- 模組功能
    return DisplayManager
  3. 建立名為 updateStatus() 的新模組功能,可以更新狀態值中的字串。其他指令碼將能夠呼叫此功能。


    -- 本地函數
    -- 模組功能
    function DisplayManager.updateStatus(newStatus)
    status.Value = newStatus
    end

更新文字狀態

設定顯示管理器後,可以在其他指令碼中使用更新 GUI 標籤。作為 GUI 的第一個訊息,顯示遊戲管理器指令碼的開始和結束。

  1. 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"))
  2. 在 while 真 do 句後的第一行, 第一個 行, updateStatus() 並在一個訊息上等待玩家。


    -- 事件
    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
  3. 在中場休息結束後,請呼叫 updateStatus() 並使用字串宣佈比賽即將開始。因為你會在 GUI 上測試,因此刪除兩個列印語式以記錄比賽開始和結束。


    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
  4. 使用 你的最低玩家。訊息應該閱讀以追蹤中內容:

    • 沒有最低玩家:"Waiting for Players"
    • 使用最小玩家:"Get ready"

排障提示

如果標籤沒有顯示第一個訊息,或仍然顯示 "Label",請從以下列中嘗試。

  • 確認 updateText() 中的 updateText 在指令碼底部。這樣玩家就會得到最新的訊息。
  • 檢查StatusStringValue是否存在在ReplicatedStorage中。由於客戶端-伺服器關係的獨特性,如果它在ServerStorage中,本地指令碼將無法找到它。

顯示觀看狀態

在比相符中,GUI 會顯示兩個數字:剩餘玩家數量和時間。當這些數字變化時,文字標籤也會變更。

設定值和函數

IntValues 會用來存儲玩家數量和剩餘時間。

  1. 在 ReplicatedStorage > DisplayValues 中,創建兩個名為 PlayersLeft 和 TimeLeft 的 IntValue。

  2. 在 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")
  3. 創建名為 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.Value
    end
  4. 對於 both IntValue 變量,連接 updateRoundStatus() 至 Changed 事件。


    -- 模組功能
    function DisplayManager.updateStatus(newStatus)
    status.Value = newStatus
    end
    playersLeft.Changed:Connect(updateRoundStatus)
    timeLeft.Changed:Connect(updateRoundStatus)
    return DisplayManager

顯示玩家

接下來,添加顯示遊戲開始時玩家數量的代碼。後續的課程將更新玩家Left值,玩家被淘汰時從遊戲中更新。

  1. 在 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.StartSpawn
    local arenaMap = workspace.Arena
    local spawnLocations = arenaMap.SpawnLocations
    -- 值
    local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
    local playersLeft = displayValues:WaitForChild("PlayersLeft")
  2. playersLeft 的值設為 playersLeft 的大小來顯示開始玩家陣列量。

    然後,在 sendPlayersToMatch() 的 for 回合中,輸入型 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

顯示計時器

記住模組指令碼是用來中央化相同的代碼。因為 Timer 會在 MatchManager 中追蹤時間,所以使用 Timer 指令碼的函數更新 TimeLeft 值。顯示管理器會偵測到 TimeLeft 的變更,並且更新以符合新值。

  1. 在 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()
  2. 找到 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()
    end
    end
  3. 使用最小玩家執行遊戲。檢查狀態文本是否顯示:

    • 正確的開始玩家數量。請記住,此數字在未來的課程中才會變更。
    • 時間會每秒鐘減少,直到它停止在 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 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

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()