BindableEvent および BindableFunction オブジェクトは、クライアント-サーバー 境界の 同じ側 でスクリプト間の動作をバインドし、ゲーム内のアクションに対して特定の望ましい結果を伝えるために使用されます。
バインダブルイベントの一般的な使用例は、ラウンドベースの構造を持つゲームです。たとえば、「マッチ開始」イベントを持っている場合、他のスクリプトがタイマーを開始し、リーダーボードを表示できるようになります。また、「マッチ終了」イベントにより、他のスクリプトはプレイヤーをロビーに戻し、勝者を表示するタイミングを知ることができます。
アクティビティをスクリプト間で調整するため、バインダブルイベントは通常サーバーで使用されますが、クライアントでも使用できます。
ゲームの動作によっては、バインダブルイベントがコードをよりモジュラーにするのに役立ちますが、スクリプト間でデータを共有する必要がある状況では、モジュールスクリプトの方が良い代替手段です。また、カスタムイベントで述べたように、モジュールスクリプトとバインダブルイベントを併用することで、よりクリーンな構文が得られます。
バインダブルイベント
BindableEvent オブジェクトは、スクリプト間で非同期の一方向通信を通じてカスタムイベントを可能にします。
BindableEvent を Fire() メソッドを通じて発火すると、発火したスクリプトは 待機せず、ターゲット関数は特定の制限に従って渡された引数を受け取ります。すべてのイベントと同様に、BindableEvents は接続された各関数のスレッドを作成しますので、1つの関数でエラーが発生しても他の関数は続行します。
Explorerウィンドウを使用して新しい BindableEvent を作成するには:
- BindableEvent を挿入したいコンテナの上にカーソルを合わせます。サーバースクリプト間の通信には ServerScriptService を、クライアントスクリプト間の通信には ReplicatedStorage を使用することをお勧めします。
- コンテナ名の右側に表示される ⊕ ボタンをクリックし、BindableEvent インスタンスを挿入します。
- インスタンスの名前を TestBindableEvent に変更します。
BindableEvent を作成した後、1つのスクリプトでその Event イベントに関数を接続し、別のスクリプトから Fire() を呼び出します。
イベント接続
local ServerScriptService = game:GetService("ServerScriptService")
-- バインダブルイベントインスタンスへの参照を取得
local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")
-- イベントに匿名関数を接続
bindableEvent.Event:Connect(function(data)
print(data) --> ラウンド開始!
end)
イベント発火local ServerScriptService = game:GetService("ServerScriptService")-- バインダブルイベントインスタンスへの参照を取得local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")-- バインダブルイベントを発火bindableEvent:Fire("ラウンド開始!")
カスタムコールバック
BindableFunction オブジェクトは、スクリプト間で同期的な双方向通信を可能にします。これを使用してカスタムコールバック関数を定義し、BindableFunction:Invoke() を手動で呼び出すことができます。関数を呼び出すコードは、対応するコールバックが見つかるまで 待機 します。また、コールバックは Invoke() に渡した引数を受け取ります。コールバックが設定されていない場合、呼び出し元スクリプトは実行を再開しません。
Explorerウィンドウを使用して新しい BindableFunction を作成するには:
- BindableFunction を挿入したいコンテナの上にカーソルを合わせます。サーバースクリプト間の通信には ServerScriptService を、クライアントスクリプト間の通信には ReplicatedStorage を使用することをお勧めします。
- コンテナ名の右側に表示される ⊕ ボタンをクリックし、BindableFunction インスタンスを挿入します。
- インスタンスの名前を TestBindableFunction に変更します。
BindableFunction を作成した後、1つのスクリプトでその OnInvoke コールバックに接続し、別のスクリプトから Invoke() を呼び出します。
コールバック接続
local ServerScriptService = game:GetService("ServerScriptService")
-- バインダブル関数への参照を取得
local bindableFunction = ServerScriptService:WaitForChild("TestBindableFunction")
-- コールバック関数
local function addTwoNumbers(a, b)
return a + b
end
-- 関数をバインダブル関数のコールバックとして設定
bindableFunction.OnInvoke = addTwoNumbers
イベント呼び出しlocal ServerScriptService = game:GetService("ServerScriptService")-- バインダブル関数への参照を取得local bindableFunction = ServerScriptService:WaitForChild("TestBindableFunction")-- コールバック関数を呼び出し、戻り値を出力local sum = bindableFunction:Invoke(2, 4)print(sum) --> 6
引数の制限
BindableEvent を発火したり BindableFunction を呼び出すと、イベントまたはコールバック関数に渡した引数がすべて転送されます。Robloxオブジェクト ( Enum 、 Instance など) や数値、文字列、ブール値などのLuau型を渡すことができますが、以下の制限を注意深く考慮する必要があります。
非文字列インデックス
渡されたテーブルの任意の インデックス が非文字列型( Instance 、userdata 、または function )である場合、Roblox は自動的にそのインデックスを文字列に変換します。
イベント接続
local ServerScriptService = game:GetService("ServerScriptService")
local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")
local function onEventFire(passedTable)
for k, v in passedTable do
print(typeof(k)) --> string
end
end
-- イベントに関数を接続
bindableEvent.Event:Connect(onEventFire)
イベント発火local ServerScriptService = game:GetService("ServerScriptService")local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")-- ワークスペースインスタンスをキーとするテーブルでイベントを発火bindableEvent:Fire({[workspace.Baseplate] = true})
テーブルのインデクシング
データのテーブルを渡す場合は、数値キーと文字列キーが混在したテーブルを渡さないでください。そうすると、転送時に要素が削除される可能性があります。その代わり、すべて のキー-値ペア(辞書)または すべて の数値インデックス(配列)で構成されるテーブルを渡してください。
イベント接続
local ServerScriptService = game:GetService("ServerScriptService")
local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")
local function onEventFire(passedTable)
for k, v in passedTable do
print(k .. " = " .. v)
--> 1 = 剣
--> 2 = 弓
--> CharName = ディーバドラゴンスレイヤー
--> CharClass = ローグ
end
end
-- イベントに関数を接続
bindableEvent.Event:Connect(onEventFire)
イベント発火local ServerScriptService = game:GetService("ServerScriptService")local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")-- 数値インデックスのテーブルlocal inventoryData = {"剣", "弓"}-- 辞書テーブルlocal characterData = {CharName = "ディーバドラゴンスレイヤー",CharClass = "ローグ"}-- 一貫してインデックスされたテーブルでイベントを発火bindableEvent:Fire(inventoryData)bindableEvent:Fire(characterData)
テーブルのアイデンティティ
バインダブルイベントとコールバックに渡される引数としてのテーブルはコピーされます。つまり、発火時またはコールバックの呼び出し時に提供されたテーブルと正確に等価ではありません。また、呼び出し元に戻されるテーブルも提供されたものとは正確には等価ではありません。以下のスクリプトを BindableFunction で実行し、テーブルのアイデンティティがどのように異なるかを観察することで、これを示すことができます。
コールバック接続
local ServerScriptService = game:GetService("ServerScriptService")
local bindableFunction = ServerScriptService:WaitForChild("TestBindableFunction")
-- コールバック関数
local function returnTable(passedTable)
-- 呼び出し時のテーブルのアイデンティティを出力
print(tostring(passedTable)) --> table: 0x48eb7aead27563d9
return passedTable
end
-- 関数をバインダブル関数のコールバックとして設定
bindableFunction.OnInvoke = returnTable
イベント呼び出しlocal ServerScriptService = game:GetService("ServerScriptService")local bindableFunction = ServerScriptService:WaitForChild("TestBindableFunction")local inventoryData = {"剣", "弓"}-- 元のテーブルのアイデンティティを出力print(tostring(inventoryData)) --> table: 0x059bcdbb2b576549local invokeReturn = bindableFunction:Invoke(inventoryData)-- 戻り値のテーブルのアイデンティティを出力print(tostring(invokeReturn)) --> table: 0x9fcae7919563a0e9
メタテーブル
テーブルにメタテーブルがある場合、転送中にすべてのメタテーブル情報が失われます。以下のコードサンプルでは、NumWheels プロパティは Car メタテーブルの一部です。サーバーが次のテーブルを受け取ると、truck テーブルには Name プロパティはありますが、 NumWheels プロパティは ありません。
イベント接続
local ServerScriptService = game:GetService("ServerScriptService")
local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")
local function onEvent(param)
print(param) --> {["Name"] = "MyTruck"}
end
-- イベントに関数を接続
bindableEvent.Event:Connect(onEvent)
イベント発火local ServerScriptService = game:GetService("ServerScriptService")local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")local Car = {}Car.NumWheels = 4Car.__index = Carlocal truck = {}truck.Name = "MyTruck"setmetatable(truck, Car)-- メタテーブルを含むテーブルでイベントを発火bindableEvent:Fire(truck)