สร้าง GUI

*เนื้อหานี้แปลโดยใช้ AI (เวอร์ชัน Beta) และอาจมีข้อผิดพลาด หากต้องการดูหน้านี้เป็นภาษาอังกฤษ ให้คลิกที่นี่

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

แสดงข้อมูลด้วย GUI

สำหรับเกมนี้ป้ายข้อความจะแสดงสถานะเกมปัจจุบันรวมถึงจํานวนผู้เล่นที่เหลือและเวลา

ระหว่างช่วงพัก
>

ในระหว่างการแข่งขัน

ตั้งค่า GUI

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

เพื่อให้แน่ใจว่าผู้เล่นทุกคนเห็นการแสดงผลเดียวกันให้วาง GUI ในโฟลเดอร์ StarterGUI เมื่อเริ่มเกมโฟลเดอร์นี้จะถูกคัดลอกไปยังผู้เล่นทุกคน

  1. ในไดเรกทอรี StarterGUI สร้าง ScreenGUI ใหม่จากนั้นใน ScreenGUI เพิ่มป้ายข้อความใหม่ที่มีชื่อว่า StatusText

  2. เพื่อย้ายป้ายชื่อใน Explorer เลือก StatusTextจากนั้นในมุมมองเกม ลากป้ายชื่อที่คุณต้องการตัวเลขของคุณอาจแตกต่างจากวิดีโอฉลากยังสามารถปรับขนาดได้โดยใช้จุดยึดในมุม

สคริปต์ GUI

เพื่อสะท้อนการเปลี่ยนแปลงในเกม สคริปต์จะต้องอัปเดตองค์ประกอบ GUIตัวอย่างเช่นสถานะเกม ไม่ว่าจะเป็นช่วงระยะหยุดหรือรอบที่ใช้งานอยู่ จะถูกเก็บไว้ใน StringValue และอัปเดตโดยใช้สคริปต์ท้องถิ่น

ตั้งค่าสคริปต์

สคริปต์ StatusDisplay จะถูกใช้เพื่ออัปเดต GUI ของผู้เล่นเมื่อสถานะเกมเปลี่ยนแปลง

  1. ใน ReplicatedStorage สร้างโฟลเดอร์ชื่อ DisplayValuesในโฟลเดอร์นั้น เพิ่ม StringValue ชื่อสถานะเพื่อทดสอบค่าในภายหลังให้ใช้ค่าชั่วคราวเช่น "ยินดีต้อนรับสู่การต่อสู้!

  2. ใน StarterGUI > ScreenGUI > สถานะ เพิ่มสคริปต์ท้องถิ่นใหม่ชื่อว่า StatusDisplay สคริปต์ที่มีผลต่อ GUI มักจะถูกผูกกับองค์ประกอบ GUI นั้น

  3. เปิดสถานะการแสดงและกำหนดตัวแปรต่อไปนี้สำหรับการติดตาม:

    • บริการ ReplicatedStorage

    • ไดเรกทอรี DisplayValues

    • ค่าสถานะ StringValue

    • ป้ายข้อความ - ใช้ script.Parent


      local ReplicatedStorage = game:GetService("ReplicatedStorage")
      local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
      local status = displayValues:WaitForChild("Status")
      local textLabel = script.Parent

เปลี่ยนฉลากข้อความ

เพื่อเปลี่ยนข้อความในฉลากใช้เหตุการณ์ที่เปลี่ยนแปลงเพื่อให้ทุกครั้งที่สตริงสถานะเปลี่ยนโดยสคริปต์อื่น ป้ายชื่อข้อความจะได้รับการอัปเดต

  1. เขียนฟังก์ชันใหม่ชื่อ updateText() ในฟังก์ชันนั้น ตั้งค่าคุณสมบัติข้อความของ textLabel เป็น status.Value


    local textLabel = script.Parent
    local function updateText()
    textLabel.Text = status.Value
    end
  2. เชื่อมฟังก์ชันกับอีเวนต์ที่เปลี่ยนแปลง


    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. เรียกเกมและยืนยันว่าคุณเห็นค่าชั่วคราวในการแสดงผล

สร้างผู้จัดการดิสเพลย์

ระหว่างเกม ป้ายข้อความจะต้องรับข้อมูลจาก GameManager, MatchManager และอาจจะเป็นสคริปต์อื่นๆดังนั้นสคริปต์ที่แตกต่างกันเหล่านี้สามารถอัปเดตฉลากข้อความเมื่อจำเป็น สร้างสคริปต์โมดูลชื่อว่า DisplayManager

ตั้งค่าสคริปต์

เนื่องจาก DisplayManager ต้องสื่อสารกับสคริปต์อื่น ๆ จะเป็นสคริปต์โมดูล

  1. ใน ServerStorage > ModuleScripts สร้างสคริปต์โมดูลใหม่ชื่อว่า DisplayManagerเปลี่ยนชื่อตารางโมดูลให้ตรงกับชื่อสคริปต์

  2. กำลังติดตาม: พื้นที่จัดเก็บซ้ำ, ไดเรกทอรี DisplayValues, สถานะ


    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 แสดงจุดเริ่มต้นและจุดสิ้นสุดของช่วงพักผ่อนผ่านสคริปต์ GameManager

  1. ใน 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"))
  2. ในฐานะที่เป็นบรรทัดแรก หลังจาก while true do สถานะ เรียก displayManager > 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" .

เคล็ดลับการแก้ปัญหา

ในจุดนี้หากป้ายข้อความไม่แสดงข้อความแรกหรือยังคงแสดง "ฉลาก" ลองหนึ่งในสิ่งต่อไปนี้

  • ตรวจสอบให้แน่ใจในสคริปต์ท้องถิ่นของ StatusDisplay ว่า updateText() ถูกเรียกที่ด้านล่างของสคริปต์ซึ่งช่วยให้แน่ใจว่าผู้เล่นจะได้รับข้อความล่าสุด
  • ตรวจสอบว่าค่าสตริงสถานะอยู่ใน ReplicatedStorageเนื่องจากลักษณะเฉพาะของความสัมพันธ์ระหว่างไคลเอนต์และเซิร์ฟเวอร์ หากอยู่ใน ServerStorage สคริปต์ท้องถิ่นจะไม่สามารถหาได้

แสดงสถานะการจับคู่

ตรงกันGUI จะแสดงตัวเลขสองตัว: จํานวนผู้เล่นที่เหลือและเวลา เมื่อตัวเลขเหล่านี้เปลี่ยนไป ป้ายชื่อข้อความก็จะเปลี่ยนไปเช่นกัน

กำหนดค่าและฟังก์ชัน

ค่า IntValues จะถูกใช้เพื่อเก็บจํานวนผู้เล่นและเวลาที่เหลือ

  1. ใน ReplicatedStorage > DisplayValues สร้าง IntValues สองตัวที่ชื่อว่า PlayersLeft และ TimeLeft

  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. สำหรับ ทั้งสอง ตัวแปร IntValue เชื่อมต่อ updateRoundStatus() กับอีเวนต์ที่เปลี่ยนแปลง


    -- ฟังก์ชันของโมดูล
    function DisplayManager.updateStatus(newStatus)
    status.Value = newStatus
    end
    playersLeft.Changed:Connect(updateRoundStatus)
    timeLeft.Changed:Connect(updateRoundStatus)
    return DisplayManager

แสดงผู้เล่น

ต่อไปให้เพิ่มโค้ดสำหรับการแสดงจํานวนผู้เล่นในตอนเริ่มต้นของเกมบทเรียนต่อมาจะอัปเดตค่า PlayersLeft เมื่อผู้เล่นถูกกําจัดออกจากเกม

  1. ใน 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.StartSpawn
    local arenaMap = workspace.Arena
    local spawnLocations = arenaMap.SpawnLocations
    -- ค่า
    local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
    local playersLeft = displayValues:WaitForChild("PlayersLeft")
  2. แสดงจํานวนผู้เล่นเริ่มต้นโดยการตั้งค่าค่าของ 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

แสดงตัวจับเวลา

โปรดจำไว้ว่าสคริปต์โมดูลใช้เพื่อกลางรหัสที่คล้ายกันเนื่องจากตัวจับเวลาถูกติดตามใน MatchManager จึงอัปเดตค่า TimeLeft โดยใช้ฟังก์ชันจากสคริปต์ Timerผู้จัดการการแสดงผลจะฟังการเปลี่ยนแปลงของ 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 คัดลอกและวางทั้งหมดที่ไฮไลต์ในขณะที่เล่นซ้ำด้านล่างโค้ดจะทำซ้ำเพื่ออัปเดตค่า 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()
    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 = (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()