Roblox エクスペリエンスはデフォルトでマルチプレイヤーですので、すべてのエクスペリエンスはサーバーとプレイヤーの接続されたクライアント間で通信します。最も単純な場合、プレイヤーがキャラクターを移動すると、特定の Humanoid プロパティ、例えば状態、がサーバーに通信され、その情報を他の接
リモートイベントとコールバックは、クライアント-サーバー境界を クロス することで通信できます:
- RemoteEvents は、一方通行通信を有効にします (リクエストを送信し、 not 応答を生成します)。
- UnreliableRemoteEvents は、ゲーム状態に関わらないデータの変更を処理するための一方通行通信を有効にします。これらのイベントは、ネットワークのパフォーマンスを向上させるために交換オーダーと信履行性を交換します。
- RemoteFunctions は、2方向通信を有効にします (リクエストを送信し、受信者からの返信を受信するまで)。
バインド可能なイベント 、バインド可能な関数 のように、限定ユーティリティの多いリモートイベントと関数の使用ケースは、リストに追加するのにはリストが長すぎます:
- ゲームプレイ - 基本的なゲームプレイ、例えばプレイヤーがレベルの終わりに到達するなど、リモートイベントが必要になる場合があります。クライアントスクリプトは、サーバーに通知し、サーバースクリプトはプレイヤーの位置をリセットします。
- サーバー検証 - プレイヤーがポーションを飲んで試した場合、そのポーションは実際に 持っている そのポーションですか? 公平性を保証するために、サーバーはエクスペリエンスのソースである必要があります。クライアントスクリプトは、リモートイベントを
- ユーザーインターフェイスの更新 - ゲーム状態が変更されると、サーバースクリプトはリモートイベントを使用して、クライアントにスコア、目標などの変更を通知できます。
- インエクスペリエンスマーケットプレイス購入 - リモート関数を使用する例の実装については、サブスクリプションの購入を促すを参照してください。
クイック参照
次の表には、RemoteEvents と RemoteFunctions を使用する方法に関するクイッサーバー参照があります。
クライアント → サーバー > | >|
---|---|
クライアント | 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 ウィンドウを通じて新しい Class.RemoteEvent を作成するには:
- Class.RemoteEvent を挿入するコンテナにカーソアクセス, 書き込み権限 (write access)を置く。サーバーとクライアントの両方にアクセスするために、それを両方のサイドが見える場所に置く必要があります。たとえ、ReplicatedStorage や、Workspace などのコンテナを
- コンテナの名前の右に表示される ⊕ ボタンをクリックし、 リモートイベント インスタンスを挿入します。
- インスタンスの名前を変更して目的を説明します。
Class.RemoteEvent を作成したら、クライアントからサーバーへの一方通行通信、サーバーからクライアントへの一方通行通信、または1>サーバーからすべてのクライアントへの一方通行通信1> を行うことができます。
クライアント → サーバー
Class.LocalScript を使用して、サーバー上のイベントをトリガーするには、FireServer()
クライアント | RemoteEvent:FireServer(args) |
サーバー | RemoteEvent.OnServerEvent:Connect(function(player, args)) |
次の Script は、サーバー上の新しい Class.Part を作成する OnServerEvent にイベ
イベント接続 - スクリプト
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- リモートイベントインスタンスの参照を取得
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))
サーバー → クライアント
Class.Script を使用して、<
サーバー | RemoteEvent:FireClient(player, args) |
クライアント | RemoteEvent.OnClientEvent:Connect(function(args)) |
次の LocalScript は、イベントハンドラーを OnClientEvent イベントに接続します。付属の Script は、サーバーから入ってくるプレイヤーをリストし、1>Class.RemoteEvent:FireClient()|FireClient()1> に電話します。これには、ランダ
イベント接続 - ローカルスクリプト
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)
サーバー → すべてのクライアント
Class.Script を使用して、FireAllClients() メソッドを RemoteEvent で呼び出すすべ
サーバー | RemoteEvent:FireAllClients(args) |
クライアント | RemoteEvent.OnClientEvent:Connect(function(args)) |
次の LocalScript は、残りのカウントダウン時間を出力する OnClientEvent イベントにイベントハンラーを接続します。Script は、1> Class.RemoteEvent:FireAllClients()|
イベント接続 - ローカルスクリプト
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 doremoteEvent:FireAllClients(countdown - timeRemaining)task.wait(1)end
リモートコールバック
Class.RemoteFunction オブジェクトは、クライアント-サーバー境界の間でシンクロした、2方通信を容易にします。リモート関数の送信者は、受信者からの応答を受信するまで生成します。
Studioの RemoteFunction ウィンドウを通じて新しい Class.RemoteFunction を作成するには:
- Class.RemoteFunction を挿入するコンテナにカーソルを置く。サーバーとクライアントの両方にアクセスするために、それを両方のサイドが見える場所に置く必要があります。たとえ、ReplicatedStorage や、Workspace などのサービスを
- コンテナの名前の右に表示される ⊕ ボタンをクリックし、 RemoteFunction インスタンスを挿入します。
- インスタンスの名前を変更して目的を説明します。
Class.RemoteFunction を作成したら、クライアントとサーバー または サーバーとクライアント 間の 2 方向通信を簡素化できます。
クライアント → サーバー → クライアント
Class.LocalScript を使用して、サーバー上の関数を呼び出すには、 Class.RemoteFunction:ExecuteServer()|Execute
クライアント | RemoteFunction:InvokeServer(args) |
サーバー | RemoteFunction.OnServerInvoke = function(player, args) |
次の Script は、OnServerInvoke を通じてコールバック関数を定義し、リクエストされた Part を 2> return 値を通じて返します。5>Class.LocalScript5>
コールバックコネクション - スクリプト
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- リモート関数インスタンスの参照を取得
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)
サーバー → クライアント → サーバー
Class.Script を使用して、クライアント上の関数を呼び出すには、InvokeClient() メソッドを 8> Class.RemoteFunction で呼び出す、但し、次のリスクがあります:
- クライアントがエラーをスローする場合、サーバーもエラーをスローします。
- クライアントが呼び出されている間に接続を解除すると、 InvokeClient() エラーが発生します。
- クライアントが値を返さない場合、サーバーは永遠に生成します。
GUI の更新など、2ウェイ通信を必要としないアクションの場合は、RemoteEvent を使用し、サーバーからクライアントへ 通信します。
引数の制限
Class.RemoteEvent を発動するか、RemoteFunction を呼び出すと、イベントまたはコールバック関数にパスするすべての引数が前に進行します。Roblox オブジェクトの任意のタイプ、例えば Enum 、
非ストリングインデックス
パスされたテーブルの任意の インデックス が、Instance 、userdata 、または2> function2> のような非ストリング型に変換されます。Roblox は、これらのインデックスを 5>文字列5> に自動的に変換します。
イベント接続 - ローカルスクリプト
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 remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- 入ってくるプレイヤーをリスニングし、各人にリモートイベントをディスパッチします
local function onPlayerAdded(player)
remoteEvent:FireClient(player,
{
[workspace.Baseplate] = true
}
)
end
Players.PlayerAdded:Connect(onPlayerAdded)
パス済み関数
Class.RemoteEvent または RemoteFunction の引数として含まれる関数は、クライアント-サーバー境界の client-server を通じてレプリケートされることはありません。代わりに、受信側の関数は 1> nil1> になります。
イベント接続 - ローカルスクリプト
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
-- 引数として機能するリモートイベントを Fire
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)
-- 呼び出しのときにテーブルのイденティティを出力
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)) --> テーブル: 0x059bcdbb2b576549local invokeReturn = remoteFunction:InvokeServer(inventoryData)-- 戻りにテーブルのイデンティティを出力print(tostring(invokeReturn)) --> table: 0x9fcae7919563a0e9
メタテーブル
テーブルにメタテーブルがある場合、メタテーブル情報はすべて、NumWheels プロパティが含まれているので、Car メタテーブルに含まれています。次のコードサンプルでは、 NumWheels</
イベント接続 - スクリプト
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 = 4Car.__index = Carlocal truck = {}truck.Name = "MyTruck"setmetatable(truck, Car)-- メタテーブルを含むテーブルでテーブルイベントを発生させるremoteEvent:FireServer(truck)
非レプリケートインスタンス
Class.RemoteEvent または RemoteFunction が、送信者にのみ表示される値をパスすると、Roblox はクライアント-サーバー境界を超えて、nil
イベント発動 - スクリプト
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- クライアントが ServerStorage にアクセスできないため、「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 remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")-- サーバーはこのパーツについて知らないため、「nil」として受信されますlocal clientPart = Instance.new("Part")clientPart.Parent = workspaceremoteEvent:FireServer(clientPart)