現在、多くのゲーム情報は、出力ウィンドウにあり、プレイヤーには見えません。そのため、プレイヤーは、ゲーム内で何が起きているか知ることができます。そのため、グラフィカルユーザーインターフェース (GUI) を作成し、コードを記述します。
GUI で情報を表示する
このゲームの場合、テキストラベルは、現在のゲーム状況と残りのプレイヤー数と時間を表示します。
GUI のセットアップ
まず、 画面GUI オブジェクトを作成して、異なるテキストエレメントを保持します。プレイヤーがカメラを移動すると、画面GUI は同じ場所に残ります。
すべてのプレイヤーが同じディスプレイを見るようにするには、GUIを スターターGUI フォルダに配置します。ゲーム起動時、このフォルダはすべてのプレイヤーにコピーされます。
スターターGUIフォルダで新しいScreenGUIを作成します。その後、ScreenGUI で新しいTextLabelを追加します。
ラベルを移動するには、エクスプローラで StatusText を選択します。次に、ゲームビューでラベルの位置をドラッグします。数字はビデオと異なる場合があります。ラベルは、隅にあるアンカーポイントを使用してサイズを変更できます。
GUI のスクリプト
ゲーム内の変更を反映するには、スクリプトは GUI 要素を更新する必要があります。たとえば、ゲームステータス、休憩中状況アクティブなラウンドかを表示するなど、StringValue に格納され、ローカルスクリプトを使用して更新されます。
スクリプトのセットアップ
ステータスディスプレイ スクリプトは、ゲームステートが変更されるたびにプレイヤーの GUI を更新します。
In ReplicatedStorage で、DisplayValues という名前のフォルダを作成します。そのフォルダには、ステータスという名前の StringValue を追加します。値を後でテストするために、一時的な値を与えて、「Welcome to the Battle!」などとします。
In StarterGui > ScreenGUI > Status、ステータスディスプレイという名前の新しいローカルスクリプトを追加します。GUI に影響を与えるスクリプトは、その GUI 要素に親が付けられます。
ステータスディスプレイを開き、次の変数をフォローのために定義してください:
ReplicatedStorage サービス
DisplayValues フォルダ
ステータスストリングバリュー
TextLabel - use script.Parent .
local ReplicatedStorage = game:GetService("ReplicatedStorage")local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")local status = displayValues:WaitForChild("Status")local textLabel = script.Parent
テキストラベルを変更する
ラベルのテキストを変更するには、[変更] イベントを使用して、ステータスストリングが別のスクリプトによって変更されるたびに、テキストラベルが更新されます。
コード a new function named 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 は他のスクリプトとコミュニケーションする必要があるため、モジュールスクリプトになります。
In ServerStorage > ModuleScripts > 新しいモジュールスクリプトを作成します。モジュールテーブルをスクリプト名に合わせて再命名します。
フォロー中の変数をローカル変数として追加します: 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テキストラベルを更新できます。GUIの開始と終了をゲームマネージャースクリプトを通じて表示します。
In ServerScriptService > GameManager, ゲームマネージャーの名前を変更する変数を作成し、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"))コールは、 while 真実であることを示すので、 最初 行後の 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 でテストするために、休憩の開始と終了を記録する 2つのプリントステートメントを削除します。
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"。
トラブルシューティングのヒント
この時点で、テキストラベルが最初のメッセージを表示しないか、まだ「ラベル」を表示している場合は、以下の 1つを試してください。
- ステータスディスプレイローカルスクリプトで updateText() がスクリプトの底部に呼び出されることを確認してください。これにより、プレイヤーが最新のメッセージを受信できます。
- ReplicatedStorage にステータスストリングバリューがあることを確認してください。 クライアント-サーバー関係のユニークな性質により、サーバーストレージにある場合、ローカルスクリプトはそれを見つけることができません。
マッチステータスを表示する
マッチ中、GUIは 2つの数字を表示します:残りプレイヤー数と時間。これらの数字が変更すると、テキストラベルも変更されます。
値と関数の設定
IntValues は、プレイヤーの数と残り時間を保存するために使用されます。
ReplicatedStorage > DisplayValues の下で、PlayerLeft と TimeLeft という名前の IntValues を 2つ作成します。
In 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")Create a local function named 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 both IntValue variables, connect updateRoundStatus() to the Changed event.
-- モジュール機能function DisplayManager.updateStatus(newStatus)status.Value = newStatusendplayersLeft.Changed:Connect(updateRoundStatus)timeLeft.Changed:Connect(updateRoundStatus)return DisplayManager
プレイヤーを表示中
次に、ゲーム開始時にプレイヤーの数を表示するコードを追加します。後のレッスンでは、プレイヤーがゲームから排除されるとプレイヤーの左側値が更新されます。
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 で追跡されるため、タイマースクリプトの機能を使用して時間左を更新します。ディスプレイマネージャーは、タイマーの変更を検出し、新しい値に更新します。
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() function. タイマーの Finished イベント後、 タイマーの Finished イベントの下で、Finished を完全にコピーして、ループを含めてコードを実行します。コードはループを実行してタイマーの timeLeft 値を更新します。
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")
-- プレイヤー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
ステータスディスプレイスクリプト
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()