目前,游戏信息的大部分已位于输出窗口,对玩家隐形。因此,玩家可以知道游戏中发生了什么,你将创建一个图形用户界面 (GUI) 并编写代码。
使用图形GUI界面显示信息
对于这个游戏,文本标签将显示当前游戏状态以及剩余玩家数量和时间。


设置 GUI
首先,创建一个 屏幕 GUI 对象来容纳不同的文本元素。当玩家移动相镜头时,屏幕图形用户界面保持在屏幕上的同一位置。
为了确保所有玩家都看到相同的显示,请将 GUI 放置在 StarterGUI 文件夹中。在游戏启动时,此文件夹将复制到所有玩家。
在新手 GUI 文件夹中,创建一个新的屏幕 GUI。然后在屏幕 GUI 中添加一个新的文本标签,名为状态文本。
要移动标签,在 Explorer 中,选择状态文本。然后,在游戏视查看中,拖动你想要的标签。您的数字可能与视频不同。标签也可以使用角落上的锚点进行调整。
脚本用户界面
要反映游戏中的更改,脚本需要更新 GUI 元素。例实例,游戏状态,是中场休息还是激活回合,将被存储在 StringValue 中,使用本地脚本进行更新。
设置脚本
状态显示脚本将用于每次游戏状态更改时更新玩家的图形用户界面。
在 复制存储 中,创建一个名为 DisplayValues 的文件夹。在那个文件夹中,添加一个名为状态的 StringValue。为了稍后测试值,给它一个临时值,例如“欢迎来到战斗!”
在启动GUI > 屏幕GUI > 状态中,添加一个名为 StatusDisplay 的新本地脚本。影响GUI 的脚本往往会被父辈到该 GUI 元素。
打开状态显示,并为跟随定义以下变量:
复制存储服务
显示值文件夹
状态字符串值
文本标签 - 使用 script.Parent .
local ReplicatedStorage = game:GetService("ReplicatedStorage")local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")local status = displayValues:WaitForChild("Status")local textLabel = script.Parent
更改文本标签
要更改标签中的文本,使用更改事件,每当状态字符串由另一个脚本更改时,文本标签都会更新。
编写一个名为 updateText() 的新函数。在该函数中,将 textLabel 的 Text 属性设置为 status.Value 。
local textLabel = script.Parentlocal function updateText()textLabel.Text = status.Valueend将函数连接到更改事件。
local function updateText()textLabel.Text = status.Valueendstatus.Changed:Connect(updateText)因此,玩家在开始游戏时看到最新状态,在脚本结束时运行 updateText()。
local function updateText()textLabel.Text = status.Valueendstatus.Changed:Connect(updateText)updateText()运行游戏并确认您在显示中看到暂时值。
创建显示管理器
在游戏期间,文本标签需要从游戏管理器、匹配管理器和可能是其他脚本获取信息。因此,这些不同的脚本可以在需要时更新文本标签,创建一个名为 DisplayManager 的模块脚本。
设置脚本
因为显示管理器需要与其他脚本进行通信,它将是一个模块脚本。
在 服务器存储 > 模块脚本 中,创建一个名为 DisplayManager 的新模块脚本。重命名模块表以匹配脚本名称。
为以关注中/正在关注添加本地变量:复制存储、显示值文件夹、状态。
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 的第一条消息,通过 GameManager 脚本显示中场休息的开始和结束。
在 服务器脚本服务 > 游戏管理器中,创建一个名为 displayManager 的变量,并要求服务器存储中的显示管理模块。
-- 服务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 true do 语句之后的第一行,调用显示管理器 > 并传递关于等待玩家的消息
-- 事件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"。
排除问题的提示
在这一点上,如果文本标签没有显示第一条消信息,或仍显示“标签”,请尝试以下方法之一。
- 确保在状态显示本地脚本中,updateText() 被调用在脚本底部。这确保玩家得到最新的消信息。
- 检查状态字符串值是否在复制存储中。由于客户端服务器关系的独特性,如果它在 ServerStorage 中,本地脚本无法找到它。
显示匹配状态
在比匹配期间,图形用户界面会显示两个数字:剩余玩家数量和时间。随着这些数字的变化,文本标签也会更改。
设置值和函数
IntValues将用于存储剩余玩家数量和时间。
在复制存储 > 显示值中,创建两个名为 PlayersLeft 和 TimeLeft 的 IntValues 值。
在 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对于 两个 IntValue 变量,连接 updateRoundStatus() 到更改事件。
-- 模块功能function DisplayManager.updateStatus(newStatus)status.Value = newStatusendplayersLeft.Changed:Connect(updateRoundStatus)timeLeft.Changed:Connect(updateRoundStatus)return DisplayManager
显示玩家
接下来,添加显示游戏开始时玩家数量的代码。之后的课程将更新玩家左值,因为玩家被淘汰出游戏。
在 PlayerManager 中,为复制存储服务、显示值文件夹和玩家左侧的 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 值到激活玩家阵数组的大小来显示初始玩家数量。
然后,在 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
显示计时器
请记住,模块脚本用于中央化相同的代验证码。由于计时器在匹配管理器中跟踪,因此使用计时器脚本中的函数更新 TimeLeft 值。显示管理器会听到 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结束后,复制并粘贴以下整体、突出显示的循环。代码会循环更新 timeLeft 值,直到计时器仍然活跃。
while myTimer:isRunning() do-- 添加 +1 可确保计时器显示结束为 1 而不是 0。timeLeft.Value = (myTimer:getTimeLeft() + 1) // 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 = (myTimer:getTimeLeft() + 1) // 1-- 通过不设置等待时间,它提供了更准确的循环task.wait()endend以最少玩家运行游戏。检查状态文本是否显示:
- 正确的起始玩家数量。请记住,此数字在未来的一堂课中添加额外代码之前不会更改。
- 时间每秒减少,直到它停止在 1 为止。
已完成的脚本
以下是完成的脚本来检查您的工作。
游戏管理器脚本
-- 服务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
显示管理器脚本
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
匹配管理器脚本
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 = (myTimer:getTimeLeft() + 1) // 1
-- 通过不设置等待时间,它提供了更准确的循环
task.wait()
end
end
-- 模块功能
function MatchManager.prepareGame()
playerManager.sendPlayersToMatch()
matchStart:Fire()
end
matchStart.Event:Connect(startTimer)
return MatchManager
状态显示脚本
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()