【Unreal Engine】アクター間通信の3つの方法:Direct Reference・Interface・Event Dispatcher

作成: 2025-12-12最終更新: 2026-09-05

Blueprintの通信を、相手の処理を直接呼ぶ・共通の操作名で頼む・登録先へ通知する、の3つで整理。Eキーで橋を出す実践を通じて、参照・Target・Bindの意味と使い分けを確かめます。

「スイッチを押したら、ドアを開けたい」。やりたいことは単純ですが、スイッチはどうやってドアへ「開け」と伝えるのでしょうか。

こうした 別のBlueprintへ処理を頼んだり、出来事を知らせたりするやり取り を、ここでは通信と呼びます。ネット対戦の通信ではなく、まずは同じゲーム内にある部品同士の連携です。

代表的な方法は、Direct Reference・Blueprint Interface・Event Dispatcher の3つです。直通電話、共通の依頼書、受信登録した人への放送を思い浮かべると、それぞれの役割をつかめます。最後に「ボタンを操作すると橋が現れる」仕掛けへ、3つを組み合わせてみましょう。

糸電話で話す2体の人形と、封筒とメガホン。Blueprint間の連絡方法を表すイメージ

この記事でわかること

  • 相手へ処理を頼むことと、起きたことを知らせることの違い
  • 3方式でも必要になる「参照」と「Target」の意味
  • Interfaceの送り先、Dispatcherの受信登録の作り方
  • 1つの仕掛けで3方式を使い、通知先を後から増やす実践

Sponsored

全体像:何を、誰へ伝えたいか

まず 参照(Reference) は、「今、処理したい相手の個体」を指す値です。レベルへ同じ設計図のドアを2枚置いても、右のドアと左のドアは別の参照になります。

ノードにある Target は、その処理を行う相手です。OpenDoorのTargetへ右のドアを渡せば、右のドアへ開くように頼みます。Targetをselfにすれば、自分自身が相手です。

方法今回の言い方
Direct Reference相手の具体的な処理を呼ぶこの橋のExtendを呼ぶ
Interface共通の操作名で頼む選んだ相手へInteractを送る
Event Dispatcher起きたことを知らせる橋が開通したと通知する

参照を使うのはDirect Referenceだけではありません。 Interfaceにも送り先が必要です。Dispatcherでは、通知を受け取る設定をするときに、発信元の参照を使います。

Direct Referenceは相手の処理を直接呼び、Interfaceは共通の操作名で頼み、Dispatcherは登録先へ知らせる。それぞれ必要な参照がある

Direct Reference:相手の処理を直接呼ぶ

相手への参照から、そのClassの関数やCustom Eventを直接呼ぶ方法です。例えば、スイッチにBP_DoorのObject Reference型変数 TargetDoor を持たせ、その参照からOpenDoorを呼びます。

これは「このドアのOpenDoorを実行して」という直通電話です。どのノードを呼んでいるかが見えやすく、特定のスイッチとドアを対応付ける仕掛けに向いています(→ Level Blueprintと配置Actorの参照)。

一方、BP_DoorのOpenDoorを呼ぶ作りには、BP_Doorとして扱える相手が必要です。別の作りの宝箱へ、そのまま置き換えられるとは限りません。こうした 相手の作りにどのくらい頼っているか を、結合度と呼びます。頼る部分が多いと密結合、少ないと疎結合です。

BP_SwitchがTargetDoorの参照からOpenDoorを呼ぶ。同じ関数を持たないBP_Chestへはそのまま置き換えられない

直接呼び出すこと自体が悪いわけではありません。同じClassの別のドアへ参照を替えたり、複数のドアを順に呼んだりする使い方もできます。「ずっと1体だけの場合しか使えない」という制限ではありません。

Blueprint Interface:共通の操作名で頼む

Blueprint Interface は、相手が受け付ける操作名と、受け渡す値を共通にする仕組みです。例えば Interact という「操作する」依頼を用意し、ドアでは開く、宝箱では中身を出す、レバーでは倒す、と各Actorで反応を作ります。

送り手は、「この相手へInteractを頼む」と書けばよく、ドア用・宝箱用・レバー用の処理を順番に探す必要がありません。共通の書式の依頼書を、選んだ相手へ渡すイメージです。

Interactという同じ操作名を、扉・宝箱・レバーで使える。実際の反応は各Actorが決める

図は、対応できる相手の例を並べています。1回のMessageで、この3つへ自動的に一斉送信されるわけではありません。MessageのTargetへ、今回操作する相手を1つ指定します。

使うときは、次の4つを揃えます。

  1. Blueprint Interfaceを作り、Interactなどの関数名を定義する。
  2. 受け手のClass Settingsへ、そのInterfaceを追加する。
  3. 受け手で、その操作に対する反応を書く。
  4. 送り手で Interact(Message) を作り、Targetへ相手の参照を渡す。

Messageを送った相手がInterfaceを実装していなければ、その操作は何も起きずに終わります。「線はつながるのに反応しない」ときは、Targetに加えて、受け手のInterface追加と処理の実装も確認します。

Interfaceには値を返す関数も作れます。まずは入力・出力なしのInteractで往復しない依頼を試し、発展はBlueprint Interfaceの記事へ進めます。

Sponsored

Event Dispatcher:登録された相手へ知らせる

Event Dispatcher は、「橋が開通した」「HPが変わった」などの出来事を、それを受け取るように設定したイベントへ知らせる仕組みです。

通知を送る操作が Call、受け取るイベントを登録する操作が Bind です。放送に例えると、受信側は「どの発信元の、どの番組を聴くか」を先に決めます。

Event Dispatcherの通知を、登録した表示・音・実績などが受け取る

例えば橋にOnBridgeExtendedを作り、表示担当と音担当が、その橋のDispatcherへそれぞれBindします。橋がCallすると両方が反応しますが、橋の開通処理の中へ「このUIを表示し、この音担当を呼ぶ」と書く必要はありません。

ここでの放送は、ゲーム中の全Actorへ無条件に届くものではありません。その個体のDispatcherへ登録したイベントだけ が呼ばれます。1つだけ登録して使うことも、複数登録することもできます。

また、Bindより前に送られた通知は、後から自動で再生されません。橋を動かす前に受信登録を済ませる、という順序も実践で確かめます(→ Event Dispatcherの接続と解除)。

使い分け:人数より、やり取りの役割を見る

「1体ならDirect、複数ならDispatcher」と人数だけで分けると、迷いやすくなります。まず、今回の連絡で何をしたいかを考えます。

やりたいこと選ぶ目安
対応する橋のExtendを呼びたいDirect Referenceで直接呼ぶ
相手がボタンでも案内板でも、同じ操作キーを使いたいInterfaceでInteractを共通にする
橋が開通した後の反応を、表示や音の担当に任せたいDispatcherで出来事を知らせる

疎結合にすると、後から別の受け手を足しやすくなります。そのぶん、登録先や実装先をたどる手間も増えます。小さな仕掛けは直接呼び出す形から始め、共通に扱いたい操作や、別の担当へ任せたい反応が見えてきたら分けて構いません。

やりたいことごとに、Direct Reference・Interface・Event Dispatcherのどれを選ぶか

実践:Eキーで橋を出し、開通を知らせる

Eキーを押すと、指定したボタンへInteractを送り、ボタンが対応する橋を出し、画面に「橋が開通した」と表示する仕掛けを作ります。

今回は3方式の接続を確かめるため、橋は板を表示する形 にします。踏む判定、伸びるアニメーション、専用HUDは、動いた後に追加できます。

開始時には見えない橋の板が、Eキーでボタンを操作すると現れ、開通メッセージが出る

① 橋とボタンの本体を作る

Third PersonのBlueprintプロジェクトを使います。Variantがある版はNoneにし、テンプレートの歩けるレベルを開きます。Actorを親にして BP_BridgeBP_FloorButton を作ります。

それぞれへStatic Meshを追加し、エンジン標準のCubeを選びます。アセット選択欄でShow Engine Contentを有効にすると、EngineのBasicShapesから選べます。

ActorMeshのScaleCollision Presets
BP_BridgeX=6、Y=2、Z=0.2BlockAll
BP_FloorButtonX=0.8、Y=0.8、Z=0.2BlockAll

両方のSimulate Physicsをオフにし、Compile・保存します。レベルへ1個ずつ置き、ActorのRotationは0、Scaleは1にします。どちらも板の高さは20cmなので、Actorの中心を床の表面から10cm上にすると下面が床に接します。

最初は平らな床の上で、細長い板が現れるかを確かめます。Play開始位置から板とボタンが見え、プレイヤーが板の上に重ならないように置いてください。

② 橋を出す処理を作る

BP_BridgeのEvent Graphで、BeginPlayから次の2つを順につなぎます。どちらもTargetはselfです。

開始時のノード設定
Set Actor Hidden In GameNew Hidden:true
Set Actor Enable CollisionNew Actor Enable Collision:false

これでPlay中の開始状態は、見えず、通り抜けられる板になります。非表示と当たり判定は別の設定 なので、両方を変えています。

BP_BridgeのBeginPlayでHiddenをtrue、Enable Collisionをfalseにする

My BlueprintのEvent Dispatchersへ OnBridgeExtended を追加します。Inputsはなしです。次にCustom Event Extend を作り、次の順で白い実行線をつなぎます。

  1. DoOnce。Start Closedはオフ、Resetは未接続。
  2. Set Actor Hidden In Game。New Hiddenはfalse。
  3. Set Actor Enable Collision。New Actor Enable Collisionはtrue。
  4. Call OnBridgeExtended。Dispatcherをドラッグして「Call」を選ぶ。

2つのSetとCallのTargetはいずれもselfです。DoOnceは、最初の1回だけ先へ進めるノードです。橋側へ置くことで、別の入口からExtendを呼んでも、同じプレイ中に開通を繰り返し通知しません。

ExtendからDoOnceを通り、橋を表示し、衝突を有効にしてからOnBridgeExtendedを呼ぶ

Compile・保存します。まだ外からExtendを呼んでいないので、Play時は板が消えたままで正常です。

③ ボタンへ「Interact」を受け付ける口を作る

Content Browserの「Blueprints → Blueprint Interface」から BPI_Interactable を作ります。最初の関数を Interact へ改名し、Inputs・Outputsはどちらも空のままCompile・保存します。Interfaceには操作名を定義し、ボタンを動かす処理は受け手へ書きます。

BP_FloorButtonを開き、Class Settings → Interfaces → Implemented InterfacesからBPI_Interactableを追加してCompileします。Event Graphで右クリックし、Interfaceの Event Interact を追加します。

ここへ同名のCustom Eventを自作するのではなく、追加したInterfaceのイベント を置きます。見つからない場合は、My BlueprintのInterfacesにあるInteractを右クリックして実装を開きます。今回は戻り値がないので、イベントとして実装できます。

④ ボタンから、対応する橋を直接呼ぶ

BP_FloorButtonへ TargetBridge 変数を作ります。型は BP_BridgeのObject Reference、Instance Editableをオンにします。Class Referenceではなく、配置した橋の個体を指す型です。

Event Interactから、白い実行ピンのある Is Valid へつなぎます。Input ObjectにはGet TargetBridgeを入れます。Is Validは、その参照先が存在し、まだ使えるかを確かめます。

Get TargetBridgeの青い出力から Extend を呼ぶノードを作り、Is Validの成功側を、その白い実行入力へつなぎます。ExtendのTargetはTargetBridgeです。Is Not Valid側は何もせず終えます。

ボタンのEvent Interactから橋の参照を確認し、有効な場合だけその橋のExtendを呼ぶ

Compile・保存したら、レベルに置いたボタン を選び、DetailsのTarget Bridgeで、対応するBP_Bridgeを指定します。Instance Editableをオンにしただけでは相手は入りません。この割り当てまで済ませます。

これがDirect Referenceの部分です。ボタンは、指定した橋のExtendという具体的な処理を呼んでいます。

⑤ 開通の通知を、先に受信登録する

Outlinerで配置した橋を選び、Blueprints → Open Level Blueprintを開きます。右クリックから「Create a reference to[橋の名前]」を選び、配置済みの橋の参照を置きます。

その青い出力から Bind Event to OnBridgeExtended を作ります。Targetはこの橋です。Event BeginPlayをBindの白い実行入力へつなぎます。

Bindの赤いEventピンからドラッグし、「Add Custom Event for Dispatcher」で ShowBridgeOpened を作ります。そのCustom Eventの白い出力からPrint Stringをつなぎ、In Stringを「橋が開通した」、Durationを10秒にします。

Bindは登録の処理、ShowBridgeOpenedは通知が来たときの反応 です。Print StringをBeginPlayやBindの直後へ置くと、橋が開通する前に表示されてしまいます。

配置した橋のOnBridgeExtendedへShowBridgeOpenedを登録する。赤い線はイベントの登録、白い線は実行順

⑥ EキーからボタンへMessageを送る

Level BlueprintへActorのObject Reference型変数 CurrentTarget を作ります。これは「今、操作する相手」です。特定のボタンClass型にはしません。

レベルへ戻ってボタンを選び、同じ方法でLevel Blueprintへ配置ボタンの参照を置きます。先ほどのBindの白い出力へSet CurrentTargetをつなぎ、値へボタンの参照を渡します。開始時に、通知の登録と操作相手の設定を済ませる形です。

Compileしてから、グラフの右クリックでキーボードのEイベントを追加します。

  1. EのPressedから、白い実行ピンのあるIs Validへつなぐ。
  2. Input ObjectへGet CurrentTargetを入れる。
  3. Get CurrentTargetの青い出力から、封筒マーク付きの Interact(Message) を作る。
  4. Is Validの成功側を、Messageの白い実行入力へつなぐ。TargetはCurrentTarget。

Is Not Valid側は何もしません。ここでは、Actor型の相手へ、BPI_Interactableで決めた操作名を送っています。Cast To BP_FloorButtonを挟む必要はありません。

EのPressedからCurrentTargetが有効か調べ、InteractのMessageをその相手へ送る

⑦ 表示と通知を確かめ、受け手を増やす

両Actor・Interface・Level BlueprintをCompile・保存してPlayします。ゲーム画面をクリックしてからEキーを押します。

確認期待する結果
Eを押す前橋の板は見えず、開通メッセージも出ない
Eを1回押す橋が現れ、その後「橋が開通した」と出る
Eを離して再び押す橋は出たまま。新しい開通メッセージは出ない
Stopして再びPlay橋が出ていない状態からやり直せる

動かなければ、E直後のPrint Stringで入力を確かめます。次にCurrentTarget、ボタンのInterface、TargetBridgeの割り当てを確認します。橋は出るのに通知がないなら、Bindの白線・Target・赤いEvent接続と、橋のCallを調べます。

次にPlayを止め、Level Blueprintへ もう1個 Bind Event to OnBridgeExtended を追加します。同じ橋をTargetにし、最初のBindの後、Set CurrentTargetの前へ白い実行線で挟みます。

新しいBindの赤いEventピンから、別のCustom Event RecordBridgeOpened を作り、Print String「記録:橋を開通」(Duration 10秒)へつなぎます。

再びPlayしてEを押すと、2種類のメッセージが出ます。橋のBlueprintを直さず、開通後の反応を増やせました。画面の上下順ではなく、両方の文が出たか で確認してください。今回は実績保存の代わりに、受信できたことをPrintで見ています。

⑧ 同じInteractを、別の種類へ送ってみる

Actorを親に BP_Sign を作り、BPI_Interactableを追加します。Event InteractからPrint String「案内板を読んだ」(Duration 10秒)をつなぎ、Compile・保存してレベルへ置きます。見た目が欲しければ、目印のCubeを追加できます。

Level Blueprintの Set CurrentTargetへ渡す参照だけ を、この配置したBP_Signへ替えます。EのMessageノードはそのままです。

PlayしてEを押すと、今度は案内板のメッセージが出て、橋は出ません。同じInteractという頼み方で、別のClassの反応を呼べました。確認後はCurrentTargetをボタンへ戻します。

Sponsored

おまけ:先に知っておくと良いこと

踏んで動くボタンや、伸びる橋にするには

今回のEキーは、通信を試すために、あらかじめ決めた相手へ送っています。目の前を狙って操作するなら、Line Traceで当たったActorをMessageのTargetへ渡します。

踏むボタンなら、Box CollisionのOverlapでプレイヤーを確認し、ボタン自身の同じ起動処理へつなぎます。検出領域の設定はトリガーで扉を開ける実践を参考にできます。

橋を徐々に伸ばすなら、Timelineで位置を変え、FinishedからOnBridgeExtendedをCall します。「動き始めた」と「開通した」を分けておくと、表示や音も適切なタイミングで反応できます。

Castは、相手の型を確かめるために使う

Castは、参照先を指定したClassとして扱えるかを確認するノードです。新しい相手を探したり、別のActorへ作り替えたりするものではありません。

特定のCharacterだけが持つ機能を使いたいなら、Castして直接呼ぶ方法が役立ちます。一方、ボタンと案内板へ同じ操作を頼む今回は、Interfaceで操作名を共通にしました。選び方はInterfaceとCastingで詳しく扱います。

受信をやめたいときはUnbindする

UIの表示対象を別の橋へ替える場合などは、古い橋のDispatcherから、自分のイベントをUnbindして、新しい橋へBindします。相手が生きていても、古い通知を受けたくなくなる場面があるためです。

「破棄時に必ず解除しないとメモリリークになる」と一律に覚えるより、誰の通知を、いつまで受けたいか を決めます。他の受信者もまとめて外すUnbind Allは、個別の解除と区別してください。

共通の状態にも、読む処理と通知は必要

ゲーム全体のスコアをGameStateなどへ集めても、UIが値を読んだり、変化を受け取ったりする連携は残ります。「置き場所を決めること」と「そこへどう連絡するか」は別です。

自作Componentも同じで、体力を減らす入口は関数、変わったことの通知はDispatcher、と分担できます。

まとめ

今回の入力側は、選んだ相手へInteractを送りました。ボタンは対応する橋のExtendを直接呼び、橋は開通したことを登録先へ知らせました。3方式は、同じ仕掛けの中で違う役割を受け持っています。

自分のグラフでも、「相手に何かしてほしいのか」「起きたことを知らせたいのか」を分けて見ると、処理の置き場所と、必要な参照が見えてきます。通知の登録を詳しく試すならEvent Dispatcher、共通の操作を増やすならBlueprint Interfaceへ進めます。

参考リンク

Unreal Engine このセクションのノート98