ตอนนี้ข้อมูลเกมส่วนใหญ่อยู่ในหน้าต่างเอาต์พุตซึ่งมองไม่เห็นสำหรับผู้เล่นดังนั้นผู้เล่นจะได้รับข้อมูลเกี่ยวกับสิ่งที่เกิดขึ้นในเกมคุณจะสร้างอินเทอร์เฟซผู้ใช้แบบกราฟิก (GUI) และโค้ดมัน
แสดงข้อมูลด้วย GUI
สำหรับเกมนี้ป้ายข้อความจะแสดงสถานะเกมปัจจุบันรวมถึงจํานวนผู้เล่นที่เหลือและเวลา


ตั้งค่า GUI
ก่อนอื่น สร้างวัตถุ หน้าจอ GUI เพื่อถือองค์ประกอบข้อความที่แตกต่างกันเมื่อผู้เล่นย้ายกล้อง อินเทอร์เฟซการแสดงผลจะยังคงอยู่ในตำแหน่งเดียวกันบนหน้าจอของพวกเขา
เพื่อให้แน่ใจว่าผู้เล่นทุกคนเห็นการแสดงผลเดียวกันให้วาง GUI ในโฟลเดอร์ StarterGUI เมื่อเริ่มเกมโฟลเดอร์นี้จะถูกคัดลอกไปยังผู้เล่นทุกคน
ในไดเรกทอรี StarterGUI สร้าง ScreenGUI ใหม่จากนั้นใน ScreenGUI เพิ่มป้ายข้อความใหม่ที่มีชื่อว่า StatusText
เพื่อย้ายป้ายชื่อใน Explorer เลือก StatusTextจากนั้นในมุมมองเกม ลากป้ายชื่อที่คุณต้องการตัวเลขของคุณอาจแตกต่างจากวิดีโอฉลากยังสามารถปรับขนาดได้โดยใช้จุดยึดในมุม
สคริปต์ GUI
เพื่อสะท้อนการเปลี่ยนแปลงในเกม สคริปต์จะต้องอัปเดตองค์ประกอบ GUIตัวอย่างเช่นสถานะเกม ไม่ว่าจะเป็นช่วงระยะหยุดหรือรอบที่ใช้งานอยู่ จะถูกเก็บไว้ใน StringValue และอัปเดตโดยใช้สคริปต์ท้องถิ่น
ตั้งค่าสคริปต์
สคริปต์ StatusDisplay จะถูกใช้เพื่ออัปเดต GUI ของผู้เล่นเมื่อสถานะเกมเปลี่ยนแปลง
ใน ReplicatedStorage สร้างโฟลเดอร์ชื่อ DisplayValuesในโฟลเดอร์นั้น เพิ่ม StringValue ชื่อสถานะเพื่อทดสอบค่าในภายหลังให้ใช้ค่าชั่วคราวเช่น "ยินดีต้อนรับสู่การต่อสู้!
ใน StarterGUI > ScreenGUI > สถานะ เพิ่มสคริปต์ท้องถิ่นใหม่ชื่อว่า StatusDisplay สคริปต์ที่มีผลต่อ GUI มักจะถูกผูกกับองค์ประกอบ GUI นั้น
เปิดสถานะการแสดงและกำหนดตัวแปรต่อไปนี้สำหรับการติดตาม:
บริการ ReplicatedStorage
ไดเรกทอรี DisplayValues
ค่าสถานะ StringValue
ป้ายข้อความ - ใช้ script.Parent
local ReplicatedStorage = game:GetService("ReplicatedStorage")local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")local status = displayValues:WaitForChild("Status")local textLabel = script.Parent
เปลี่ยนฉลากข้อความ
เพื่อเปลี่ยนข้อความในฉลากใช้เหตุการณ์ที่เปลี่ยนแปลงเพื่อให้ทุกครั้งที่สตริงสถานะเปลี่ยนโดยสคริปต์อื่น ป้ายชื่อข้อความจะได้รับการอัปเดต
เขียนฟังก์ชันใหม่ชื่อ updateText() ในฟังก์ชันนั้น ตั้งค่าคุณสมบัติข้อความของ textLabel เป็น 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()เรียกเกมและยืนยันว่าคุณเห็นค่าชั่วคราวในการแสดงผล
สร้างผู้จัดการดิสเพลย์
ระหว่างเกม ป้ายข้อความจะต้องรับข้อมูลจาก GameManager, MatchManager และอาจจะเป็นสคริปต์อื่นๆดังนั้นสคริปต์ที่แตกต่างกันเหล่านี้สามารถอัปเดตฉลากข้อความเมื่อจำเป็น สร้างสคริปต์โมดูลชื่อว่า DisplayManager
ตั้งค่าสคริปต์
เนื่องจาก DisplayManager ต้องสื่อสารกับสคริปต์อื่น ๆ จะเป็นสคริปต์โมดูล
ใน ServerStorage > ModuleScripts สร้างสคริปต์โมดูลใหม่ชื่อว่า DisplayManagerเปลี่ยนชื่อตารางโมดูลให้ตรงกับชื่อสคริปต์
กำลังติดตาม: พื้นที่จัดเก็บซ้ำ, ไดเรกทอรี DisplayValues, สถานะ
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
ใน ServerScriptService > GameManager สร้างตัวแปรชื่อ displayManager และต้องใช้โมดูล 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 true do สถานะ เรียก displayManager > 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" .
เคล็ดลับการแก้ปัญหา
ในจุดนี้หากป้ายข้อความไม่แสดงข้อความแรกหรือยังคงแสดง "ฉลาก" ลองหนึ่งในสิ่งต่อไปนี้
- ตรวจสอบให้แน่ใจในสคริปต์ท้องถิ่นของ StatusDisplay ว่า updateText() ถูกเรียกที่ด้านล่างของสคริปต์ซึ่งช่วยให้แน่ใจว่าผู้เล่นจะได้รับข้อความล่าสุด
- ตรวจสอบว่าค่าสตริงสถานะอยู่ใน ReplicatedStorageเนื่องจากลักษณะเฉพาะของความสัมพันธ์ระหว่างไคลเอนต์และเซิร์ฟเวอร์ หากอยู่ใน ServerStorage สคริปต์ท้องถิ่นจะไม่สามารถหาได้
แสดงสถานะการจับคู่
ตรงกันGUI จะแสดงตัวเลขสองตัว: จํานวนผู้เล่นที่เหลือและเวลา เมื่อตัวเลขเหล่านี้เปลี่ยนไป ป้ายชื่อข้อความก็จะเปลี่ยนไปเช่นกัน
กำหนดค่าและฟังก์ชัน
ค่า IntValues จะถูกใช้เพื่อเก็บจํานวนผู้เล่นและเวลาที่เหลือ
ใน ReplicatedStorage > DisplayValues สร้าง IntValues สองตัวที่ชื่อว่า PlayersLeft และ TimeLeft
ใน 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
แสดงผู้เล่น
ต่อไปให้เพิ่มโค้ดสำหรับการแสดงจํานวนผู้เล่นในตอนเริ่มต้นของเกมบทเรียนต่อมาจะอัปเดตค่า PlayersLeft เมื่อผู้เล่นถูกกําจัดออกจากเกม
ใน PlayerManager เพิ่มตัวแปรท้องถิ่นสำหรับบริการ ReplicatedStorage, ไดเรกทอรี DisplayValues และ 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
แสดงตัวจับเวลา
โปรดจำไว้ว่าสคริปต์โมดูลใช้เพื่อกลางรหัสที่คล้ายกันเนื่องจากตัวจับเวลาถูกติดตามใน MatchManager จึงอัปเดตค่า TimeLeft โดยใช้ฟังก์ชันจากสคริปต์ Timerผู้จัดการการแสดงผลจะฟังการเปลี่ยนแปลงของ 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 คัดลอกและวางทั้งหมดที่ไฮไลต์ในขณะที่เล่นซ้ำด้านล่างโค้ดจะทำซ้ำเพื่ออัปเดตค่า timeLeft จนกว่าตัวนับเวลาจะยังคงใช้งานอยู่
while myTimer:isRunning() do-- การเพิ่ม +1 ทำให้แน่ใจว่าการแสดงเวลาของตัวนับจะสิ้นสุดที่ 1 แทน 0timeLeft.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 แทน 0timeLeft.Value = (myTimer:getTimeLeft() + 1) // 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 = (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()