GUI の作成

*このコンテンツは、ベータ版のAI(人工知能)を使用して翻訳されており、エラーが含まれている可能性があります。このページを英語で表示するには、 こちら をクリックしてください。

現在、多くのゲーム情報は、出力ウィンドウにあり、プレイヤーには見えません。そのため、プレイヤーは、ゲーム内で何が起きているか知ることができます。そのため、グラフィカルユーザーインターフェース (GUI) を作成し、コードを記述します。

GUI で情報を表示する

このゲームの場合、テキストラベルは、現在のゲーム状況と残りのプレイヤー数と時間を表示します。

インターミッション中
マッチ中

GUI のセットアップ

まず、 画面GUI オブジェクトを作成して、異なるテキストエレメントを保持します。プレイヤーがカメラを移動すると、画面GUI は同じ場所に残ります。

すべてのプレイヤーが同じディスプレイを見るようにするには、GUIを スターターGUI フォルダに配置します。ゲーム起動時、このフォルダはすべてのプレイヤーにコピーされます。

  1. スターターGUIフォルダで新しいScreenGUIを作成します。その後、ScreenGUI で新しいTextLabelを追加します。

  2. ラベルを移動するには、エクスプローラで StatusText を選択します。次に、ゲームビューでラベルの位置をドラッグします。数字はビデオと異なる場合があります。ラベルは、隅にあるアンカーポイントを使用してサイズを変更できます。

GUI のスクリプト

ゲーム内の変更を反映するには、スクリプトは GUI 要素を更新する必要があります。たとえば、ゲームステータス、休憩中状況アクティブなラウンドかを表示するなど、StringValue に格納され、ローカルスクリプトを使用して更新されます。

スクリプトのセットアップ

ステータスディスプレイ スクリプトは、ゲームステートが変更されるたびにプレイヤーの GUI を更新します。

  1. In ReplicatedStorage で、DisplayValues という名前のフォルダを作成します。そのフォルダには、ステータスという名前の StringValue を追加します。値を後でテストするために、一時的な値を与えて、「Welcome to the Battle!」などとします。

  2. In StarterGui > ScreenGUI > Status、ステータスディスプレイという名前の新しいローカルスクリプトを追加します。GUI に影響を与えるスクリプトは、その GUI 要素に親が付けられます。

  3. ステータスディスプレイを開き、次の変数をフォローのために定義してください:

    • 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

テキストラベルを変更する

ラベルのテキストを変更するには、[変更] イベントを使用して、ステータスストリングが別のスクリプトによって変更されるたびに、テキストラベルが更新されます。

  1. コード a new function named 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. In ServerStorage > ModuleScripts > 新しいモジュールスクリプトを作成します。モジュールテーブルをスクリプト名に合わせて再命名します。

  2. フォロー中の変数をローカル変数として追加します: Replicated Storage、DisplayValues フォルダ、Status。


    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の開始と終了をゲームマネージャースクリプトを通じて表示します。

  1. 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"))
  2. コールは、 while 真実であることを示すので、 最初 行後の 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 でテストするために、休憩の開始と終了を記録する 2つのプリントステートメントを削除します。


    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. ゲームをテストする with および without あなたの最小プレイヤー。メッセージはフォロー中のように読み取る必要があります:

    • 最小プレイヤーがない場合: "Waiting for Players"
    • 最小プレイヤーと一緒に: "Get ready"

トラブルシューティングのヒント

この時点で、テキストラベルが最初のメッセージを表示しないか、まだ「ラベル」を表示している場合は、以下の 1つを試してください。

  • ステータスディスプレイローカルスクリプトで updateText() がスクリプトの底部に呼び出されることを確認してください。これにより、プレイヤーが最新のメッセージを受信できます。
  • ReplicatedStorage にステータスストリングバリューがあることを確認してください。 クライアント-サーバー関係のユニークな性質により、サーバーストレージにある場合、ローカルスクリプトはそれを見つけることができません。

マッチステータスを表示する

マッチ中、GUIは 2つの数字を表示します:残りプレイヤー数と時間。これらの数字が変更すると、テキストラベルも変更されます。

値と関数の設定

IntValues は、プレイヤーの数と残り時間を保存するために使用されます。

  1. ReplicatedStorage > DisplayValues の下で、PlayerLeft と TimeLeft という名前の IntValues を 2つ作成します。

  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")
  3. 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.Value
    end
  4. For both IntValue variables, connect updateRoundStatus() to the Changed event.


    -- モジュール機能
    function DisplayManager.updateStatus(newStatus)
    status.Value = newStatus
    end
    playersLeft.Changed:Connect(updateRoundStatus)
    timeLeft.Changed:Connect(updateRoundStatus)
    return DisplayManager

プレイヤーを表示中

次に、ゲーム開始時にプレイヤーの数を表示するコードを追加します。後のレッスンでは、プレイヤーがゲームから排除されるとプレイヤーの左側値が更新されます。

  1. 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.StartSpawn
    local arenaMap = workspace.Arena
    local spawnLocations = arenaMap.SpawnLocations
    -- 値
    local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
    local playersLeft = displayValues:WaitForChild("PlayersLeft")
  2. 「playersLeft」の値をアクティブなプレイヤーの陣サイズに設定して、開始プレイヤーの数を表示します。

    その後、sendPlayersToMatch() の下で、ループの下に、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 で追跡されるため、タイマースクリプトの機能を使用して時間左を更新します。ディスプレイマネージャーは、タイマーの変更を検出し、新しい値に更新します。

  1. 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()
  2. 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()
    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 を追加すると、タイマーが 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()