現在、ゲーム情報の多くは出力ウィンドウにあり、プレイヤーには見えません。そのため、プレイヤーはゲームで何が起こっているかを知ることができ、グラフィカルユーザーインターフェイス (GUI) を作成し、コード化します。
GUI で情報を表示
このゲームでは、テキストラベルが現在のゲーム状態と残りのプレイヤー数、時間を表示します。


GUI を設定する
まず、異なるテキスト要素を保持する スクリーンGUI オブジェクトを作成します。プレイヤーがカメラを移動すると、画面のGUIが同じ場所に残ります。
すべてのプレイヤーが同じ表示を見るようにするには、GUI を スターターGUI フォルダに配置します。ゲーム起動時、このフォルダはすべてのプレイヤーにコピーされます。
スターターGUI フォルダで、新しいスクリーンGUI を作成します。次に、スクリーンGUI で [ステータステキスト] という新しいテキストラベルを追加します。
ラベルを移動するには、エクスプローラで [ステータステキスト] を選択します。次に、ゲームビューで、好きなラベルをドラッグします。ビデオと数字が異なる可能性があります。ラベルは、隅のアンカーポイントを使用してサイズを変更することもできます。
GUI をスクリプトする
ゲームの変更を反映するには、スクリプトは GUI 要素を更新する必要があります。たとえば、ゲームの状状況(インターミッションかアクティブラウンドかなど)は、StringValue に保存され、ローカルスクリプトを使用して更新されます。
スクリプトを設定する
ステータスディスプレイスクリプトは、ゲーム状態が変更されるたびにプレイヤーのGUIを更新するのに使用されます。
In ReplicatedStorage で、ディスプレイバリューという名前のフォルダを作成します。そのフォルダに、ステータスという名前の StringValue を追加します。後で値をテストするには、一時的な値 "Welcome to the Battle!" のように与えます。
スターターGUI > スクリーンGUI > ステータスでは、ステータスディスプレイという新しいローカルスクリプトを追加します。GUIに影響を与えるスクリプトは、多くの場合、その GUI 要素に親属します。
ステータスディスプレイを開き、次の変数を追跡するために定義しまフォロー:
ReplicatedStorage サービス
ディスプレイバリューフォルダ
ステータスのストリング値
テキストラベル - 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 サーバーストレージ > モジュールスクリプト , 新しいモジュールスクリプトを作成して、名前を DisplayManager のモジュールスクリプト。モジュールテーブルをスクリプト名に合わせて名前変更する。
フォロー中のためのローカル変数を追加: リプリケートストレージ、表示値フォルダ、ステータス。
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 サーバースクリプトサービス > ゲームマネージャーで、変数名 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 true 文が発行された後の 最初の 行で、call 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 でテストするので、インターミッションの開始と終了を記録するための 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ゲームをテスト と 最低プレイヤーなしで 、メッセージはフォロー中のように読む必要があります:
- 最低プレイヤーがない場合: "Waiting for Players"。
- 最低プレイヤー数で: "Get ready"。
トラブルシュートのヒント
この時点で、テキストラベルが最初のメッセージを表示しない、またはまだ「ラベル」を表示している場合は、以下のいずれかを試してください。
- ステータスディスプレイのローカルスクリプトで updateText() がスクリプトの底に呼ばれることを確認してください。これにより、プレイヤーが最新のメッセージを受け取ることが保証されます。
- ステータス弦値が ReplicatedStorage にあるかどうかをチェックします。クライアント-サーバー関係のユニークな性質により、ServerStorage にある場合、ローカルスクリプトで見つけることはできません。
マッチ状状況を表示
一致合中、GUI は 2つの数字を表示します:残りのプレイヤー数と時間。これらの数字が変更されると、テキストラベルも変更されます。
値と機能を設定する
IntValues は、プレイヤー数と残り時間を保存するために使用されます。
ReplicatedStorage > DisplayValues で、PlayersLeft と TimeLeft という名前の 2つの IntValue を作成します。
ディスプレイマネージャでは、残りのプレイヤーと残り時間の値を保存する変数を追加します。
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.ValueendFor 両方の 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
タイマーを表示
モジュールスクリプトは、同様のコードを中央化するために使用されることを覚えてください。タイマーは MatchManager で追跡されるため、タイマースクリプトの関数を使用して TimeLeft 値を更新します。ディスプレイマネージャは、TimeLeft の変更を聞き取り、新しい値に合わせて更新します。
マッチマネージャーでは、 ReplicatedStorage サービス、ディスプレイバリューフォルダ、および 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 を追加すると、タイマーの表示が 0 ではなく 1 で終わることを保証できます。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 を追加すると、タイマーの表示が 0 ではなく 1 で終わることを保証できます。timeLeft.Value = (myTimer:getTimeLeft() + 1) // 1-- 待機時間を設定しないことで、より正確なループが提供されますtask.wait()endend最小プレイヤーでゲームを実行し、ステータステキストが表示されているか確認します:
- 開始プレイヤーの正しい数。将来のレッスンで追加コードが追加されるまで、この数は変更されません。
- 時間は 1 に停止するまで、毎秒減少します。
完了したスクリプト
以下は、作業を確認するための完了したスクリプトです。
ゲームマネージャースクリプト
-- サービス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 = (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()