リモートイベントとコールバック

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

Roblox の経験はデフォルトでマルチプレイヤーであるため、すべての経験は本質的にサーバーとプレイヤーの接続クライアント間で通信します。最も単純な場合、プレイヤーがキャラクターを移動すると、状態などの特定の Humanoid プロパティがサーバーに伝達され、この情報を他の接続されたクライアントに伝達します。

リモートイベントとコールバックでは、クライアント-サーバー境界を越えて 通信することができます

  • RemoteEvents 一方通行通信を有効にし(リクエストを送信し、 応答を受け取らない )。
  • UnreliableRemoteEvents 一方通行通信を有効にして、連続的に変更されたりゲーム状態にクリティカルでないデータを変更するこれらのイベントは、ネットワークのパフォーマンスを向上させるために注文の履行先度と信頼性を取引します。
  • RemoteFunctions 二方向通信を有効にして (リクエストを送信して受信者から返答を受けるまで待つ)。

バインド可能なイベント とは異なり、より限られた機能を持つリモートイベントと機能の使用ケースは列挙するのが困難すぎます:

  • ゲームプレイ - プレイヤーがレベルの終わりに到達するなどの基本的なゲームプレイには、リモートイベントが必要になる可能性があります。クライアントスクリプトがサーバーに通知し、サーバースクリプトはプレイヤーの位置をリセットします。
  • サーバー認証 - プレイヤーがポーションを飲もうとした場合、実際にそのポーションを持っていますか?公平性を保証するために、サーバーはエクスペリエンスの源である必要があります。クライアントスクリプトは、リモートイベントを使用して、サーバーにプレイヤーがポーションを飲んでいることを通知し、サーバースクリプトは、プレイヤーが実際にそのポーションを持っているかどうかと、どのような利益を与えるかを決定できます。
  • ユーザーインターフェイスの更新 - ゲーム状態が変化すると、サーバースクリプトはリモートイベントを使用して、スコア、目標などの変更をクライアントに通知できます
  • 経験中のマーケットプレイス購入 - リモート関数を使用する例の実装の例は、プロンプトサブスクリプション購入 を参照してください。

クイック参照

次の表は、RemoteEventsRemoteFunctions を使用して、クライアントとサーバー間でコミュニケーションする方法の迅速な参照として機能します。

クライアント → サーバー
クライバーRemoteEvent:FireServer(args)
サーバーRemoteEvent.OnServerEvent:Connect(function(player, args))
サーバー → クライアント
サーバーRemoteEvent:FireClient(player, args)
クライバーRemoteEvent.OnClientEvent:Connect(function(args))
サーバー → すべてのクライアント
サーバーRemoteEvent:FireAllClients(args)
クライバーRemoteEvent.OnClientEvent:Connect(function(args))

リモートイベント

A RemoteEvent オブジェクトは、応答を諦めずにクライアント-サーバー境界を横断して非同期、一方通行の通信を容易にします。

Studio の RemoteEvent ウィンドウを介して新しい を作成するには:

  1. 挿入したい RemoteEvent をコンテナにホバーします。両方のサーバーとクライアントへのアクセスを保証するには、ReplicatedStorage など、両側がそれを見ることができる場所に配置する必要がありますが、いくつかの場合、Workspace または内部の Tool に保存することが適切です。
  2. コンテナの名前の右側に表示される ボタンをクリックし、 RemoteEvent インスタンスを挿入します。
  3. インスタンスの名前を変更して目的を説明する。

を作成したら、クライアントからサーバーへの一方通行通信、サーバーからクライアントへの一方通行通信、またはサーバーからすべてのクライアントへの一方通行通信を簡素化できます。

クライアント → サーバー
サーバー → クライアント
サーバー → すべてのクライアント

クライアント→サーバー

You can use a LocalScript を使用して、サーバー でイベントをトリガーするには、FireServer() メソッドを RemoteEvent で呼び出します。FireServer() に引数を渡すと、特定の 制限 を持つサーバーのイベントハンドラーにパスします。サーバー上のイベントハンドラーの最初のパラメータは、呼び出すクライアントの Player オブジェクトであり、追加パラメータがフォローきます。

クライバーRemoteEvent:FireServer(args)
サーバーRemoteEvent.OnServerEvent:Connect(function(player, args))

次の は、サーバー上で新しい を作成するイベントハンドラーに接続します。付随する は、必要な と および のための部分の インスタンスを呼び出します。

イベント接続 - スクリプト

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- リモートイベントインスタンスへの参照を取得
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onCreatePart(player, partColor, partPosition)
print(player.Name .. " fired the RemoteEvent")
local newPart = Instance.new("Part")
newPart.Color = partColor
newPart.Position = partPosition
newPart.Parent = Workspace
end
-- 機能をイベントに接続する
remoteEvent.OnServerEvent:Connect(onCreatePart)
イベント発射 - ローカルスクリプト

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- リモートイベントインスタンスへの参照を取得
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- リモートイベントを発射して追加の引数をパスする
remoteEvent:FireServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))

サーバー → クライアント

You can use a Script を使用して、クライアント にイベントをトリガーする方法として、FireClient() メソッドを RemoteEvent に呼び出して、イベントを発動できます。FireClient() の最初の引数は、イベントに応答したいクライアントの Player オブジェクトであり、追加の引数は特定の 制限 でクライアントにパスします。イベントハンドラーには、Player オブジェクトを最初の引数として含める必要はありません、Players.LocalPlayer でクライアント上のプレイヤーを決定できるため。

サーバーRemoteEvent:FireClient(player, args)
クライバーRemoteEvent.OnClientEvent:Connect(function(args))

次の LocalScript は、イベントハンドラーを OnClientEvent イベントに接続します。付属の Script は、サーバーに到着するプレイヤーをリスニングし、それぞれにランダムなデータで FireClient() を呼び出します。

イベント接続 - ローカルスクリプト

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- リモートイベントインスタンスへの参照を取得
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local player = Players.LocalPlayer
local function onNotifyPlayer(maxPlayers, respawnTime)
print("[Client] Event received by player", player.Name)
print(maxPlayers, respawnTime)
end
-- 機能をイベントに接続する
remoteEvent.OnClientEvent:Connect(onNotifyPlayer)
イベント発射 - スクリプト

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- リモートイベントインスタンスへの参照を取得
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- 入ってくるプレイヤーを聞き、それぞれにリモートイベントを派遣する
local function onPlayerAdded(player)
print("[Server] Firing event to player", player.Name)
remoteEvent:FireClient(player, Players.MaxPlayers, Players.RespawnTime)
end
Players.PlayerAdded:Connect(onPlayerAdded)

サーバー → すべてのクライアント

You can use a Script を使用して、すべてのクライアントにイベントをトリガーするには、FireAllClients() メソッドを RemoteEvent で呼び出します。FireClient() とは異なり、FireAllClients() メソッドはすべてのクライアントに Player を発射するため、RemoteEvent オブジェクトは必要ありません。

サーバーRemoteEvent:FireAllClients(args)
クライバーRemoteEvent.OnClientEvent:Connect(function(args))

次の LocalScript は、残りのカウントダウン時間を出力するイベントハンドラーに接続します OnClientEvent イベント。付随する Script は、それぞれの秒にループで FireAllClients() を呼び出し、すべてのクライアントに対して RemoteEvent を発射します。

イベント接続 - ローカルスクリプト

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- リモートイベントインスタンスへの参照を取得
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onTimerUpdate(seconds)
print(seconds)
end
-- 機能をイベントに接続する
remoteEvent.OnClientEvent:Connect(onTimerUpdate)
イベント発射 - スクリプト

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- リモートイベントインスタンスへの参照を取得
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local countdown = 5
-- 時間切れまで、リモートイベントを毎秒発射する
for timeRemaining = -1, countdown do
remoteEvent:FireAllClients(countdown - timeRemaining)
task.wait(1)
end

リモートコールバック

A RemoteFunction オブジェクトは、クライアント-サーバー境界を介した同期的な 2 方向通信を容易にします。リモート関数の送信者は、受信者からの応答を受け取るまで生成し続けます。

Studio の RemoteFunction ウィンドウを介して新しい を作成するには:

  1. 挿入したい RemoteFunction をコンテナにホバーします。両方のサーバーとクライアントへのアクセスを保証するには、ReplicatedStorage など、両側がそれを見ることができる場所に配置する必要がありますが、いくつかの場合、Workspace または内部の Tool に保存することが適切です。
  2. コンテナの名前の右側に表示される ボタンをクリックし、 RemoteFunction インスタンスを挿入します。
  3. インスタンスの名前を変更して目的を説明する。

を作成したら、 クライアントとサーバー または サーバーとクライアント の間の双方向通信を簡素化できます。

クライアント → サーバー → クライアント
サーバー → クライアント → サーバー

クライアント → サーバー → クライアント

You can use a LocalScript を使用して、サーバー で関数を呼び出すには、InvokeServer() メソッドを RemoteFunction で呼び出します。リモートイベントとは異なり、 リモートイベント が呼び出される は、コールバックが返されるまで生成されます。パスする InvokeServer() 引数は、OnServerInvoke 特定の 制限 を持つ RemoteFunction コールバックにパスします。同じ RemoteFunction に複数のコールバックを定義する場合、最後の定義のみが実行されることに注意してください。

クライバーRemoteFunction:InvokeServer(args)
サーバーRemoteFunction.OnServerInvoke = function(player, args)

次の Script は、OnServerInvoke を介してコールバック関数を定義し、Part の値を通じてリクエストされた return を返します。付属の LocalScript は、要求されたパーツの色と位置を定義する追加の引数を持つ InvokeServer() を呼び出します。

呼び出しコネクション - スクリプト

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- リモート関数インスタンスへの参照を取得する
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- 呼び出し機能
local function createPart(player, partColor, partPosition)
print(player.Name .. " requested a new part")
local newPart = Instance.new("Part")
newPart.Color = partColor
newPart.Position = partPosition
newPart.Parent = Workspace
return newPart
end
-- 機能をリモート関数のコールバックとして設定
remoteFunction.OnServerInvoke = createPart
イベントの呼び出し - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- リモート関数インスタンスへの参照を取得する
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- コールバックを呼び出すときに色と位置をパスする
local newPart = remoteFunction:InvokeServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))
-- 返されたパーツ参照を出力する
print("The server created the requested part:", newPart)

サーバー → クライアント → サーバー

を使用して、 メソッドを呼び出してクライアントに機能を呼び出すことができますが、次のような重大なリスクがあります:

  • クライアントがエラーをスローすると、サーバーもエラーをスローします。
  • クライアントが呼び出されている間に切断されると、InvokeClient() がエラーをスローします。
  • クライアントが値を返さない場合、サーバーは永久に返します。

GUI を更新するなど、2方向通信が必要ないアクションには、RemoteEvent を使用し、サーバーからクライアントへ を通信します。

引数の制限

When you fire a RemoteEvent or invoke a RemoteFunction , it forwards any arguments that you pass with the event or to the callback function.EnumInstance などの Roblox オブジェクトの任意の種類、または数字、文字列、ブールのような Luau タイプもパスできますが、次の制限を注意深く調べる必要があります。

非ストリングインデックス

パスされたテーブルのどの インデックス も、Instanceuserdata 、または 機能 のような非ストリングタイプの場合、Roblox は自動的にそれらのインデックスを文字列に変換します。

イベント接続 - ローカルスクリプト

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEventFire(passedTable)
for k, v in passedTable do
print(typeof(k)) --> 文字列
end
end
-- 機能をイベントに接続する
remoteEvent.OnClientEvent:Connect(onEventFire)
イベント発射 - スクリプト

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- 入ってくるプレイヤーを聞き、それぞれにリモートイベントを派遣する
local function onPlayerAdded(player)
remoteEvent:FireClient(player,
{
[Workspace.Baseplate] = true
}
)
end
Players.PlayerAdded:Connect(onPlayerAdded)

パスされた関数

または の引数として含まれる機能は、 クライアント-サーバー境界 を介して機能をリプリケートすることはできません、機能をリモートでパスすることは不可能になります。代わりに、受信側の結果の引数は nil になります。

イベント接続 - ローカルスクリプト

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onClientEvent(func)
print(func) --> ゼロ
end
remoteEvent.OnClientEvent:Connect(onClientEvent)
イベント発射 - スクリプト

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function testFunction()
print("Hello world!")
end
-- 機能を引数としてリモートイベントを発火する
remoteEvent:FireAllClients(testFunction)

テーブルインデックス作成

データのテーブルをパスする場合、数字と文字列のキーの混合テーブルをパスしないでください。代わりに、キー-バリューペア(辞書) または数値インデックスの完全に構成されたテーブルをパスします。

イベント接続 - スクリプト

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEventFire(player, passedTable)
for k, v in passedTable do
print(k .. " = " .. v)
--> 1 = ソード
--> 2 = ボウ
--> CharName = ディヴァドラゴンスレイヤー
--> CharClass = 悪者
end
end
-- 機能をイベントに接続する
remoteEvent.OnServerEvent:Connect(onEventFire)
イベント発射 - ローカルスクリプト

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- 数字でインデックスされたテーブル
local inventoryData = {
"Sword", "Bow"
}
-- 辞書テーブル
local characterData = {
CharName = "Diva Dragonslayer",
CharClass = "Rogue"
}
remoteEvent:FireServer(inventoryData)
remoteEvent:FireServer(characterData)

テーブルの識別子

リモートイベント/コールバックに渡されたテーブルは、引数としてコピーされ、つまりイベントを発射するか、コールバックを呼び出すときに提供されるものと同等ではないことになります。また、インボーカーに返されるテーブルは、提供されたものと完全に同等ではありません。これを示すには、RemoteFunction で次のスクリプトを実行し、テーブルの識別がどのように異なるかを観察することができます。

呼び出しコネクション - スクリプト

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- 呼び出し機能
local function returnTable(player, passedTable)
-- 呼び出し時の出力テーブルID 識別
print(tostring(passedTable)) --> テーブル: 0x48eb7aead27563d9
return passedTable
end
-- 機能をリモート関数のコールバックとして設定
remoteFunction.OnServerInvoke = returnTable
イベントの呼び出し - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
local inventoryData = {
"Sword", "Bow"
}
-- オリジナルのテーブルIDを出力
print(tostring(inventoryData)) --> テーブル: 0x059bcdbb2b576549
local invokeReturn = remoteFunction:InvokeServer(inventoryData)
-- 返却時の出力テーブルID 識別
print(tostring(invokeReturn)) --> table: 0x9fcae7919563a0e9

メタテーブル

テーブルにメタテーブルがある場合、すべてのメタテーブル情報が転送中に失われます。次のコードサンプルでは、NumWheels プロパティは Car メタテーブルの一部です。サーバーが次の表を受信すると、 テーブルには プロパティがありますが、 プロパティはありません。

イベント接続 - スクリプト

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEvent(player, param)
print(param) --> {["Name"] = "MyTruck"}
end
-- 機能をイベントに接続する
remoteEvent.OnServerEvent:Connect(onEvent)
イベント発射 - ローカルスクリプト

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local Car = {}
Car.NumWheels = 4
Car.__index = Car
local truck = {}
truck.Name = "MyTruck"
setmetatable(truck, Car)
-- メタテーブルを含むテーブルで発火イベント
remoteEvent:FireServer(truck)

非リプリケートインスタンス

または が送信者にしか見えない値をパスした場合、Roblox はクライアント-サーバー境界を越えてそれを複製しないで、代わりに をパスします。たとえば、ScriptServerStorage の子孫をパスした場合、イベントを聴いているクライアントは、そのオブジェクトがクライアントに再現できないため、nil 値を受け取ります。

イベント発射 - スクリプト

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- クライアントがサーバーストレージにアクセスできないため、「nil」として受信されます
local storedPart = Instance.new("Part")
storedPart.Parent = ServerStorage
local function onPlayerAdded(player)
remoteEvent:FireClient(player, storedPart)
end
Players.PlayerAdded:Connect(onPlayerAdded)

同様に、LocalScript でパーツを作成し、それを Script にパスしようとすると、サーバーはパーツがサーバーにレプリケーションできないため、nil を見ます。

イベント発射 - ローカルスクリプト

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- サーバーがこの部分について知らないため、「ゼロ」として受信されます
local clientPart = Instance.new("Part")
clientPart.Parent = Workspace
remoteEvent:FireServer(clientPart)