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

作成: 2025-12-12

Blueprintでアクター同士がやり取りする方法は主に3つ。それぞれの結合度や汎用性の違いを理解して、場面に応じた使い分けを解説。

Blueprintでアクター間通信を行う方法は主に3つあります:「Direct Reference(直接参照)」「Blueprint Interface(インターフェース)」「Event Dispatcher(イベントディスパッチャー)」です。

この記事では、これら3つの通信方法の特性と使い分けを解説します。

Direct Reference(直接参照)

概要と使い方

Direct Reference は、最もシンプルで直感的な通信方法です。特定のBlueprintクラスの変数や関数を直接呼び出す方法で、「このアクターの、この関数を実行する」という明確な指示を出します。

使用例:

  • プレイヤーキャラクターが、目の前にある特定の「ドア」アクターのOpenDoor関数を呼び出す。
  • 親クラスが、子クラスの特定のコンポーネントのプロパティを直接変更する。

Blueprintの例(プレイヤーからドアへの参照):

  1. ドアアクター(BP_Door)の参照をプレイヤーアクター(BP_Player)の変数に格納します(例: BeginPlay時やOverlapイベント時)。
  2. その変数からピンを引っ張り出し、呼び出したい関数(例: OpenDoor)を直接検索して実行します。
// BP_Playerのイベントグラフ
// 参照変数: TargetDoor (型: BP_Door)
If TargetDoor Is Valid:
    Call TargetDoor.OpenDoor()

メリット・デメリット

メリットデメリット
実装が簡単 で、学習コストが低い。依存性が高い (Tight Coupling)。
パフォーマンスが良い。参照先のアクターが変更されると、参照元も修正が必要になる。
処理の流れが追いやすい。汎用性が低く、再利用が難しい。

ベストプラクティス

  • 特定の単一のアクター との通信や、親子関係など構造が固定されている 場合に限定して使用しましょう。
  • 参照を取得する際は、必ずIsValidノードで参照が有効かチェックする習慣をつけましょう。

Blueprint Interface(インターフェース)

概要と使い方

Blueprint Interface は、C++のインターフェースに相当する機能で、「このメッセージを受け取ったら、どう処理するかは受け取り側が決める 」という、契約のようなものです。

インターフェース自体は処理を持ちません。インターフェースで定義された関数(メッセージ)を実装したアクターであれば、どのクラスであっても そのメッセージを受け取ることができます。これにより、通信元は通信相手の具体的なクラスを知る必要がなくなります(疎結合 )。

使用例:

  • プレイヤーが「インタラクト」ボタンを押したとき、目の前にある「ドア」「スイッチ」「宝箱」など、インタラクト可能な全てのアクターInteractメッセージを送る。

Blueprintの例(Interfaceの作成と使用):

  1. Interfaceの作成: BPI_Interactableというインターフェースを作成し、Interactという関数を定義します。
  2. 実装: ドア(BP_Door)や宝箱(BP_Chest)のクラス設定でBPI_Interactableを実装します。
  3. 処理の記述: 各アクターのイベントグラフにEvent Interactノードが出現するので、それぞれの処理(ドアを開ける、宝箱を開ける)を記述します。
  4. 呼び出し: プレイヤー側は、目の前のアクターに対してMessage Interactノードを呼び出すだけです。
// BP_Playerのイベントグラフ
// TargetActor: 目の前のアクター (型: Actor)
Call TargetActor.Interact (Message)

メリット・デメリット

メリットデメリット
疎結合 (Loose Coupling)を実現し、拡張性・保守性が高い。Direct Referenceに比べて実装手順が多い
複数の異なるクラスに対して共通のメッセージ を送れる。処理がインターフェースと実装クラスに分散するため、追跡が少し複雑 になる。
汎用性が高く、再利用しやすい。

ベストプラクティス

  • 「〜できるもの」 という共通の機能を持たせたい場合に積極的に使用しましょう(例: BPI_Damageable, BPI_Usable)。
  • プロジェクトの初期段階から、汎用的な通信にはInterfaceを使うことを検討しましょう。

💡 補足:Interfaceでも戻り値は使える

Blueprint Interfaceの関数は、戻り値(Output)を定義できます。例えば、BPI_InteractableGetInteractionText関数で、インタラクト時に表示するテキストを返すような設計が可能です。戻り値がある場合、呼び出し側でMessageノードではなく通常の関数呼び出しノードを使用します。


Event Dispatcher(イベントディスパッチャー)

概要と使い方

Event Dispatcher は、特定のイベントが発生したことを、そのイベントに興味を持っている全てのアクター に通知するための仕組みです。これは「一対多 」の通信(1つの発生源から複数のリスナーへ)であり、プログラミングにおける「オブザーバーパターン 」(またはPublish-Subscribeパターン)とも呼ばれます。

通信元はイベントを「発火」させるだけで、誰がそのイベントを受け取るかを知る必要はありません。通信相手は、事前にイベントに「バインド(登録)」しておく必要があります。

使用例:

  • UIの「ゲーム開始」ボタンが押されたとき、プレイヤー、ゲームモード、BGM管理アクターなど、複数のアクター に通知する。
  • 敵が倒されたとき、スコアUI、ドロップアイテム生成システム、実績システムなど、複数のシステム に通知する。

Blueprintの例(Event Dispatcherの作成と使用):

  1. Dispatcherの作成: イベント発生源のアクター(例: BP_GameMode)にOnGameOverというEvent Dispatcherを作成します。
  2. 発火: ゲームオーバーになったタイミングでCall OnGameOverノードを実行します。
  3. バインド: 通知を受け取りたいアクター(例: BP_ScoreUI)のBeginPlayなどで、Bind Event to OnGameOverノードを使って、カスタムイベントを登録します。
// BP_ScoreUIのイベントグラフ (バインド)
Bind Event to OnGameOver (Event: Custom Event ScoreUpdate)

// BP_GameModeのイベントグラフ (発火)
Call OnGameOver

メリット・デメリット

メリットデメリット
多対一の通知 が非常に容易。バインドとアンバインドの管理が必要。
通信元と通信相手が完全に独立している(最も疎結合 )。処理の流れが追いにくくなることがある。
UI操作やゲーム状態の変化など、グローバルなイベント に適している。

ベストプラクティス

  • イベントを受け取ったアクターが不要になったら、必ずUnbind Eventノードで登録を解除(アンバインド)し、メモリリークを防ぎましょう。
  • ゲーム全体に影響するイベント (ゲーム開始/終了、ポーズ、スコア更新など)に使うと効果的です。

3つの通信方法の使い分け

どの通信方法を選ぶべきか迷ったときは、以下のフローチャートと比較表を参考にしてください。

通信方法の選択フローチャート

  1. 通信相手は特定の単一アクターか?
    • YesDirect Reference を検討。ただし、将来的に通信相手が増える可能性があるならInterfaceへ。
    • No → 次へ。
  2. 通信相手は「同じ機能を持つ複数の異なるクラス」か?
    • YesBlueprint Interface。疎結合で拡張性を確保。
    • No → 次へ。
  3. イベントを「不特定多数」に通知したいか?
    • YesEvent Dispatcher。UIやゲーム状態の通知に最適。

比較表

通信方法結合度汎用性主な用途
Direct Reference高い(密結合)低い特定の単一アクター、親子間通信
Interface低い(疎結合)高い共通機能を持つ複数の異なるアクター
Event Dispatcher最も低い(疎結合)高いUIイベント、ゲーム状態のグローバル通知

よくある間違い

  • 全てをDirect Referenceで済ませる: 初期は楽ですが、プロジェクトが大きくなると修正コストが爆発的に増大します。汎用的な機能にはInterfaceを使いましょう。
  • Interfaceのメッセージを実装し忘れる: Interfaceを実装したのに、対応するEventノードをイベントグラフに配置し忘れると、メッセージは無視されます。
  • Event Dispatcherのアンバインド忘れ: アクターが破棄される際にアンバインドしないと、存在しないアクターにイベントが送られ続け、パフォーマンス低下や予期せぬエラーの原因になります。

通信方法の選択指針

Unreal EngineのBlueprintにおける通信方法は、ゲームの設計思想そのものです。

  • Direct Reference は、手軽な個別会話
  • Interface は、共通のルールに基づいたビジネス会話
  • Event Dispatcher は、不特定多数へのニュース速報

これらの特性を理解し、適切な場面で使い分けることで、あなたのUnreal Engineプロジェクトはより堅牢で、拡張性の高いものになるでしょう。まずは小さなプロジェクトでInterfaceとEvent Dispatcherを試してみて、そのメリットを実感してください。