현재 게임 정보의 대부분은 출력 창에 있으며 플레이어가 볼 수 없습니다. 그래서 플레이어가 게임에서 무슨이 일이 일어나고 있는지 알 수 있도록 그래픽 사용자 인터페이스 (GUI)를 만들고 코드를 작성합니다.
GUI로 정보 표시
이 게임에는 텍스트 레이블이 현재 게임 상태와 남은 플레이어 수 및 시간을 표시합니다.
GUI 설정
먼저, 다양한 텍스트 요소를 보관하기 위해 화면 가이 개체를 생성합니다. 플레이어가 카메라를 이동할 때 화면 가이는 화면에 동일한 위치에 남아 있습니다.
모든 플레이어가 동일한 표시를 볼 수 있도록 하려면 게임 시작 시 StarterGui 폴더에 GUI를 배치하십시오. 게임 시작 시 이 폴더는 모든 플레이어에게 복사됩니다.
스타터 GUI 폴더에서 새로운 스크린 GUI를 생성합니다. 그런 다음 스크린 GUI에 새로운 텍스트 레이블 이름인 StatusText를 추가합니다.
레이블을 이동하려면 탐색기에서 상태 텍스트를 선택합니다. 그런 다음 게임 뷰에서 레이블을 원하는 곳으로 드래그하십시오. 숫자는 비디오와 다를 수 있습니다. 레이블은 모서리에 있는 앵커 포인트를 사용하여 확대/축소할 수 있습니다.
GUI 스크립트
게임에 변경 사항을 반영하려면 스크립트는 GUI 요소를 업데이트해야 합니다. 예를 인스턴스, 게임 상태, 중간 휴식 또는 활성 라운드인지 여부는 문자열 값에 저장되고 로컬 스크립트를 사용하여 업데이트됩니다.
스크립트 설정
StatusDisplay 스크립트는 플레이어의 GUI를 업데이트하는 데 사용됩니다.
In ReplicatedStorage 에서 이름이 DisplayValues인 폴더를 생성합니다. 그 폴더에는 Status라는 이름의 StringValue를 추가합니다. 나중에 값을 테스트하려면 임시 값을 지정하십시오, 예를 들어 "Welcome to the Battle!" 입니다.
In StarterGui > ScreenGUI > Status, add a new local script named StatusDisplay. 스크립트가 GUI에 영향을 주는 경우 해당 GUI 요소에 부모로 지정됩니다.
Open StatusDisplay를 열고 다음 변수를 팔로우:
ReplicatedStorage 서비스
DisplayValues 폴더
상태 문자열 값
텍스트 레이블 - 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는 다른 스크립트와 통신해야 하기 때문에 모듈 스크립트가 될 것입니다.
In ServerStorage > ModuleScripts > 새로운 모듈 스크립트 이름 DisplayManager를 만듭니다. 모듈 테이블을 스크립트 이름과 일치하게 이름 변경합니다.
팔로잉위해 로컬 변수 추가: Replicated Storage, DisplayValues 폴더, Status.
local DisplayManager = {}-- 서비스local ReplicatedStorage = game:GetService("ReplicatedStorage")-- Player GUI를 업데이트하는 데 사용되는 값 표시local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")local status = displayValues:WaitForChild("Status")-- 로컬 함수-- 모듈 함수return DisplayManagerupdateStatus()라는 이름의 새로운 모듈 함수를 생성하여 상태 값에 문자열을 업데이트합니다. 다른 스크립트는 이 함수를 호출할 수 있습니다.
-- 로컬 함수-- 모듈 함수function DisplayManager.updateStatus(newStatus)status.Value = newStatusend
텍스트 상태 업데이트
디스플레이 관리자를 설정하면 다른 스크립트에서 GUI 텍스트 레이블을 업데이트할 수 있습니다. 게임 관리자 스크립트를 통해 시작 및 종료 간격을 표시합니다.
In ServerScriptService > GameManager, create a variable named displayManager 및 ServerStorage의 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"))잠시 진행 상황에 대해 첫 번째 줄 후에, 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게임을 테스트하십시오 with 및 without 최소 플레이어. 메시지는 팔로잉같이 읽어야 합니다.
- 최소 플레이어가 없는 경우: "Waiting for Players" .
- 최소 플레이어: "Get ready" .
문제 해결 팁
이 시점에서 텍스트 레이블이 첫 번째 메시지를 표시하지 않거나 "레이블"이 여전히 표시되면 다음 중 하나를 시도하십시오.
- StatusDisplay 로컬 스크립트에서 updateText() 이 스크립트의 하단에 호출되도록 하세요. 이렇게 하면 플레이어가 최신 메시지를 받습니다.
- ReplicatedStorage의 StatusStringValue이 있는지 확인하십시오. 클라이언트-서버 관계의 특별한 성격으로 인해 서버스토리지에 있는 경우 로컬 스크립트는 찾을 수 없습니다.
매치 상태 표시
일치중에 GUI는 다음과 같은 숫자를 표시합니다: 남은 플레이어 수 및 시간. 이 숫자가 변경되면 텍스트 레이블도 변경됩니다.
값 및 함수 설정
IntValues는 플레이어 수 및 남은 시간을 저장하는 데 사용됩니다.
ReplicatedStorage > DisplayValues에서 PlayersLeft 및 TimeLeft라는 이름의 IntValues를 두 개 생성합니다.
In DisplayManager에서 플레이어가 남은 시간 및 시간 남은 값을 저장하도록 변수를 추가합니다.
local DisplayManager = {}-- 서비스local ReplicatedStorage = game:GetService("ReplicatedStorage")-- Player 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.ValueendFor 둘 모두 IntValue 변수 를 연결하려면 Changed 이벤트에 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() 의 루프 아래에서 입력: 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에서 추적되므로 Timer 스크립트에서 시간 왼쪽 값을 업데이트하십시오. 표시 관리자는 타이머에 변경 내용을 감지하고 새 값에 일치하도록 업데이트합니다.
In 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()Find the startTimer() 함수. 후에 타이머의 Finished 이벤트 이후, 코드를 루프 아래에 복사하고 전체를 붙여넣습니다. 코드는 타이머가 활성인 동안 1> timeLeft1> 값을 업데이트하기 위해 루프를 실행합니다.
while myTimer:isRunning() do-- +1을 추가하면 타이머가 0이 아닌 1로 표시됩니다.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을 추가하면 타이머가 0이 아닌 1로 표시됩니다.timeLeft.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")
-- Player 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을 추가하면 타이머가 0이 아닌 1로 표시됩니다.
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()