GUIを作成する

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

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

GUI で情報を表示

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

インターミッション中
試合中

GUI を設定する

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

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

  1. スターターGUI フォルダで、新しいスクリーンGUI を作成します。次に、スクリーンGUI で [ステータステキスト] という新しいテキストラベルを追加します。

  2. ラベルを移動するには、エクスプローラで [ステータステキスト] を選択します。次に、ゲームビューで、好きなラベルをドラッグします。ビデオと数字が異なる可能性があります。ラベルは、隅のアンカーポイントを使用してサイズを変更することもできます。

GUI をスクリプトする

ゲームの変更を反映するには、スクリプトは GUI 要素を更新する必要があります。たとえば、ゲームの状状況(インターミッションかアクティブラウンドかなど)は、StringValue に保存され、ローカルスクリプトを使用して更新されます。

スクリプトを設定する

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

  1. In ReplicatedStorage で、ディスプレイバリューという名前のフォルダを作成します。そのフォルダに、ステータスという名前の StringValue を追加します。後で値をテストするには、一時的な値 "Welcome to the Battle!" のように与えます。

  2. スターターGUI > スクリーンGUI > ステータスでは、ステータスディスプレイという新しいローカルスクリプトを追加します。GUIに影響を与えるスクリプトは、多くの場合、その GUI 要素に親属します。

  3. ステータスディスプレイを開き、次の変数を追跡するために定義しまフォロー:

    • ReplicatedStorage サービス

    • ディスプレイバリューフォルダ

    • ステータスのストリング値

    • テキストラベル - 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」という名前のモジュールスクリプトを作成します。

スクリプトを設定する

ディスプレイマネージャーは他のスクリプトとコミュニケーションする必要があるため、モジュールスクリプトになります。

  1. In サーバーストレージ > モジュールスクリプト , 新しいモジュールスクリプトを作成して、名前を DisplayManager のモジュールスクリプト。モジュールテーブルをスクリプト名に合わせて名前変更する。

  2. フォロー中のためのローカル変数を追加: リプリケートストレージ、表示値フォルダ、ステータス。


    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 サーバースクリプトサービス > ゲームマネージャーで、変数名 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 true 文が発行された後の 最初の 行で、call 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 でテストするので、インターミッションの開始と終了を記録するための 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. ゲームをテスト と 最低プレイヤーなしで 、メッセージはフォロー中のように読む必要があります:

    • 最低プレイヤーがない場合: "Waiting for Players"
    • 最低プレイヤー数で: "Get ready"

トラブルシュートのヒント

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

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

マッチ状状況を表示

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

値と機能を設定する

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

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

  2. ディスプレイマネージャでは、残りのプレイヤーと残り時間の値を保存する変数を追加します。


    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. For 両方の 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 フォルダ、および 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() で、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 値を更新します。ディスプレイマネージャは、TimeLeft の変更を聞き取り、新しい値に合わせて更新します。

  1. マッチマネージャーでは、 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()
  2. 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()
    end
    end
  3. 最小プレイヤーでゲームを実行し、ステータステキストが表示されているか確認します:

    • 開始プレイヤーの正しい数。将来のレッスンで追加コードが追加されるまで、この数は変更されません。
    • 時間は 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 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 = (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()