この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:8
ページ更新者:T
更新日時:2026-06-11 07:10:02

タイトル: どこからでも呼び出せるカスタムイベントを作成する方法
SEOタイトル: UE5 グローバル カスタム イベント作成完全ガイド(GameInstance/Subsystem/Event Dispatcher)

この記事の要点
  • UE のカスタムイベントをレベル横断・どこからでも呼ぶ定石は GameInstance に Event Dispatcher を置くパターン
  • GameInstance はゲーム起動から終了までレベル切替を跨いで生き続けるシングルトン的存在
  • モダンな方法は UGameInstanceSubsystem。機能単位で分離でき、依存最小
  • Blueprint からは Get Game InstanceCast ToBind Event to ...Call ...
  • 責務に応じて: PlayerController / GameMode / GameState / GameInstance / Subsystem を使い分け、Blueprint Interface はインタフェース契約に

「どこからでも呼べる」の意味

UE5 で「Blueprint からどこからでも呼び出せるカスタムイベント」を作りたい場合、その本質はグローバルな置き場(シングルトン)を確保することです。レベル(マップ)が切り替わるたびに破棄されない場所に、イベントの発信源を置きます。

置き場寿命用途
GameInstanceゲーム起動〜終了レベル跨ぎグローバル(推奨)
GameInstanceSubsystemゲーム起動〜終了機能別分割(モダン推奨)
GameStateレベル切替で破棄マップ内グローバル
GameModeレベル切替で破棄(サーバのみ)ルール定義
PlayerControllerプレイヤー単位入力・UI 制御
個別 Actorそのレベルのみローカル機能

方法1: GameInstance に Event Dispatcher を置く

最も古典的で確実な方法です。次の手順で進めます。

  1. Content Browser → 右クリック → Blueprint ClassGame Instance を継承 → BP_MyGameInstance
  2. Project Settings → Maps & Modes → Game Instance ClassBP_MyGameInstance に変更
  3. BP_MyGameInstance を開き、Event Dispatchers ペインで OnEnemyDefeated 等を追加
  4. イベント発信側: Get Game InstanceCast To BP_MyGameInstanceCall OnEnemyDefeated
  5. イベント受信側: 同様に Cast → Bind Event to OnEnemyDefeated → カスタムイベントに接続
[Enemy_BP]              [HUD_BP]
   ↓ Defeated             ↓ BeginPlay
Get Game Instance       Get Game Instance
   ↓                       ↓
Cast To BP_MyGameInstance  Cast To BP_MyGameInstance
   ↓                       ↓
Call OnEnemyDefeated      Bind Event to OnEnemyDefeated
                            ↓
                         Custom Event: UpdateScore

方法2: GameInstanceSubsystem(推奨・モダン)

UE 4.22+ で導入された UGameInstanceSubsystem は、GameInstance を肥大化させずに機能ごとに分離できるモダンな仕組みです。Blueprint からは Get Game Instance Subsystem (BP_QuestSubsystem) でいきなり取れるため、Cast 不要でアクセスできます。

// MyQuestSubsystem.h
#pragma once
#include "CoreMinimal.h"
#include "Subsystems/GameInstanceSubsystem.h"
#include "MyQuestSubsystem.generated.h"

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnQuestCompleted, FName, QuestId);

UCLASS()
class MYGAME_API UMyQuestSubsystem : public UGameInstanceSubsystem
{
    GENERATED_BODY()
public:
    UPROPERTY(BlueprintAssignable, Category="Quest")
    FOnQuestCompleted OnQuestCompleted;

    UFUNCTION(BlueprintCallable, Category="Quest")
    void CompleteQuest(FName QuestId)
    {
        OnQuestCompleted.Broadcast(QuestId);
    }
};

Blueprint からは以下のように使えます。

[発信側]
Get Game Instance Subsystem (MyQuestSubsystem)
   → Complete Quest (QuestId="DragonSlain")

[受信側 - BeginPlay 等で]
Get Game Instance Subsystem (MyQuestSubsystem)
   → Bind Event to On Quest Completed
   → Custom Event handler でクエスト UI 更新

方法3: Blueprint Interface

「呼び方の契約」だけ共有したい場合は Blueprint Interface を使います。シングルトンとは異なり、対象 Actor が分かっているケースで利用します。

  1. Content Browser → Blueprint Interface → BPI_Damageable 作成
  2. Function: ReceiveDamage(int32 Amount) を追加
  3. 各 Actor の Class Settings → Interfaces → Add で BPI_Damageable を実装
  4. 呼ぶ側: Receive Damage (Message) ノードで、Target に Actor を渡す

方法4: シーン跨ぎの永続データ

イベントだけでなく値も保持したいなら、GameInstance のメンバ変数(Save Game との連携も)を使います。

用途置き場備考
レベル間のスコア/所持金GameInstance 変数メモリ上のみ。閉じると消える
セーブデータSaveGame オブジェクトファイル書き込み
ステージ間の進捗GameInstance + SaveGame両立
ネットワーク同期データGameState / Replicatedマルチプレイ向け

レベル間通信のフロー例

Level_Field(フィールドマップ)
  Player が敵に勝利
    → GameInstance.OnVictory(EnemyId, Reward) を呼ぶ
    → GameInstance に Reward を保存
    → Open Level "Level_Result"

Level_Result(リザルト画面)
  BeginPlay
    → Get Game Instance.GetReward() で値取得
    → UI に表示

注意点と落とし穴

  • GameInstance クラスを設定し忘れると、いくら Blueprint を作っても使われない(Project Settings 必須)
  • Subsystem は引数なしの Initialize しか持てない。データは Initialize 内で別から取得
  • Event Dispatcher の Bind は重複防止のために Unbind を意識。EndPlay で Unbind All を推奨
  • Actor が破棄された後でも Bind が残るとクラッシュリスク。Weak Reference / EndPlay で確実に解除
  • マルチプレイ環境では、GameInstance はクライアント/サーバそれぞれにあるため、同期は別途 Replication 設計が必要

C++ から Multicast Delegate を公開する

// マルチキャストデリゲートで Blueprint からも Bind 可能に
UCLASS(Blueprintable)
class UMyEventBus : public UGameInstanceSubsystem
{
    GENERATED_BODY()
public:
    DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnPause);
    UPROPERTY(BlueprintAssignable) FOnPause OnPause;

    UFUNCTION(BlueprintCallable) void Pause() { OnPause.Broadcast(); }
};

FAQ

Q: GameInstance と Subsystem、どちらを使うべき?
A: 新規プロジェクトは Subsystem。GameInstance を肥大化させず機能ごとに分離できます。既存プロジェクトの拡張なら GameInstance に追加で問題なし。

Q: PlayerController に置くのとどう違う?
A: PlayerController はプレイヤー単位。ローカルマルチでは複数生成され、レベル切替で破棄されます。ゲーム全体のイベントには不向き。

Q: Bind がリークしたとき?
A: 破棄済 Actor のハンドラに Broadcast すると Access None / クラッシュの原因になります。Actor の EndPlay で Unbind を呼ぶ習慣を。