Workspace.SignalBehavior プロパティは、イベントハンドラーが即座に発火されるか、遅延されるかを制御します。Enum.SignalBehavior.Deferred オプションが推奨されており、エンジンのパフォーマンスと正確性を向上させるのに役立ちます。遅延イベントのイベントハンドラーは、次の 再開ポイント で、新たにトリガーされたイベントハンドラーと共に再開されます。
以下の図は、Immediate のイベント動作と Deferred のイベント動作を比較しています。
- Immediate 動作の場合、イベントが別のイベントをトリガーすると、2 番目のイベントハンドラーが即座に発火します。
- Deferred 動作の場合、2 番目のイベントはキューの最後に追加され、後で実行されます。
かかる合計時間は変わりませんが、順序が異なります。

「再入性」は、イベントが特定の深さに達したときに互いに連続して発火し続けるのを防ぎます。現在の制限は 10 です。
遅延イベントの利点
Immediate 動作にはいくつかの欠点があります。ゲームに追加される各インスタンス、変更されるプロパティ、または何か他のトリガーが発動するたびに、エンジンは他の何かが起こる前に Luau コードを実行する必要があります。
- 1,000 のプロパティを変更するには、各変更後に 1,000 のコードスニペットが実行される可能性があります。
- 何かが追加される前に削除イベントが発火するなど、異常で診断が困難なバグが発生する可能性があります。
- パフォーマンスが重要なシステムは、Luau に戻ってやり取りするためにイベントを発火させる可能性があります。
- イベントハンドラーは、イベントが発火するたびにプレイスを変更したり、他のイベントをトリガーしたりすることができます。
- プロパティが 2 回変更されるといったように、冗長にもかかわらずイベントが複数回発火することがあります。
Luau が実行できるエンジンライフサイクルの特定の部分を持つことで、エンジンは次のような多くの仮定を使用してパフォーマンスを向上させることができます。
- パフォーマンスが重要なシステムは Luau に戻る必要がないため、パフォーマンスが向上します。
- エンジン自体が変更しない限り、プレイスは再開ポイントの外では決して変更されません。
再開ポイント
遅延されたイベントハンドラーは、次の再開ポイントで再開されます。現在、再開ポイントのセットには以下が含まれます。
- 入力処理(処理中の入力ごとに再開、UserInputService を参照)
- wait()、spawn()、delay() などのレガシーウェイティングスクリプトの再開
一般的に影響を受けるコードパターン
リモートイベントでは、次の例が正しく動作しなくなったり、微妙に異なる動作をする可能性があります。それらはイベントが即座に再開されることに依存しています。
実行中にイベントをトリガーしてキャッチ
この例では、遅延イベントが有効になっているときは常に false が返されます。なぜならコールバックが実行されていないからです。正しく機能するためには、スレッドはイベントが発火すべきタイミングまで待機する必要があります。
local success = false
event:Connect(function ()
success = true
end)
doSomethingToTriggerEvent() -- `event` を発火させる
return success
イベントの最初の発生を監視する
connection = event:Connect(function ()
connection:Disconnect()
-- 何かをする
end)
遅延イベントが有効になっている場合、イベントから切断する前に複数のイベントハンドラーの呼び出しがキューに追加される可能性があります。Disconnect() を呼ぶと、すべての保留中のイベントハンドラー呼び出しが削除されます—これは即時イベントに対して存在するのと同じ動作です。
あるいは、最初の呼び出しだけが必要なイベントに接続するためのより便利な方法として Once() を使用できます。
系譜やプロパティが変更されるイベント
遅延イベントは、系譜やプロパティの変更を扱うイベントが系譜やプロパティが変更された後に発火することを引き起こします:
local part = Instance.new("Part", workspace)
local function onPartDestroying()
print("シグナル内:", part:GetFullName(), #part:GetChildren())
end
part.Destroying:Connect(onPartDestroying)
part:Destroy()
Destroy() は、呼び出したスクリプトが待機した後に即座に動作するため、onPartDestroying() が呼ばれた時点ですでにインスタンスは削除されています。詳細な例については、Instance.Destroying を参照してください。