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