この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:5
ページ更新者:atom
更新日時:2026-06-12 15:50:03

タイトル: 動的にインスタンスが属するレベルを変更する方法
SEOタイトル: UE5でアクターが属するレベルを動的に扱う方法|Level StreamingとData Layer

Unreal Engine 5(UE5)では、実行中にアクター(インスタンス)が「どのレベルに属するか」を変更する場合、スポーン時に所属レベルを指定するか、レベル(ストリーミングレベル/World PartitionのData Layer)単位でロード・アンロードを制御するのが基本的な考え方です。すでに存在するアクターを、別レベルへ「そのまま移し替える」ランタイム用の標準APIはエンジンに用意されていないため、実務では「移送先レベルに新規スポーンして元を破棄する」手法や、最初から適切なレベル/Data Layerに配置しておく設計で対応します。

この記事の要点
  • アクターが属するレベル(ULevel)は、原則としてスポーンされた時点で決まります。実行中に所属を切り替えたいときは「どのレベルにスポーンするか」を制御するのが出発点です。
  • UE5には大きく分けて従来のLevel Streaming(永続レベル+サブレベル)World Partitionの2系統があり、両者は併用できないため、まずプロジェクトがどちらを使っているかを確認します。
  • Level Streaming環境では、レベルのロード/アンロード(Load Stream Level・Unload Stream Level)でレベル単位の表示・存在を制御します。アクター個体は配置先・スポーン先のレベルに属します。
  • すでに存在するアクターを別レベルへ移送する確実なランタイムAPIは限定的で、実務では移送先レベルへの再スポーン+元アクターの破棄や、参照(Object Reference)の保持で対応するのが一般的です。
  • World Partition環境では、サブレベルの代わりにData Layerとストリーミングソースでアクター群のロード状態を制御します。Data Layerの状態切り替えはブループリントから可能です。
  • レベル間のアクター移送は、参照切れ・座標(Transform)の扱い・ストリーミングのタイミングといった落とし穴を伴います。仕様の細部はバージョンで変わるため、最終的には公式ドキュメントでの確認を推奨します。

前提:UE5には「レベルの考え方」が2系統ある

UE5でアクターの所属レベルを動的に扱う前に、プロジェクトがどの仕組みでレベルを管理しているかを把握しておく必要があります。これによって取れる手段が変わります。

項目従来のLevel StreamingWorld Partition
レベル構成永続レベル(Persistent Level)+複数のサブレベル1つの大きなレベルをグリッドで自動分割
ロード単位サブレベル単位(手動・ボリューム・ブループリント)セル単位+Data Layer(ストリーミングソース基準)
アクターの分類配置・スポーン先のサブレベルに属する空間位置とData Layerで自動的にセルへ振り分け
主な制御Load/Unload Stream Level などData Layerの状態切り替え、ストリーミングソース
併用World PartitionとレベルストリーミングのワークフローはUE5では併用しない設計です(プロジェクト単位でどちらかを選ぶ前提)。

「どのレベルにアクターが属するか」という問いは、Level Streamingではサブレベルへの所属、World PartitionではどのData Layer/空間セルに含まれるかとして現れます。以降は両系統に分けて整理します。

アクターの所属レベルは「スポーン時」に決まる

UE5において、アクター(ULevelに属するインスタンス)の所属レベルは、エディタでの配置時、またはランタイムのスポーン時に確定します。C++では SpawnActor に渡す FActorSpawnParametersOverrideLevel に対象の ULevel* を指定することで、スポーン先レベルを明示できます。OverrideLevel を指定しない場合は、ワールドの現在のレベル(パーシステントレベルなど、エンジンが決める既定のレベル)にスポーンされます。

// C++:スポーン先のレベルを明示する例(概念)

FActorSpawnParameters SpawnParams;

SpawnParams.OverrideLevel = TargetLevel; // 移送先にしたい ULevel* を指定

AMyActor* NewActor = GetWorld()->SpawnActor<AMyActor>(MyClass, SpawnTransform, SpawnParams);

このため「実行中にアクターを別レベルへ所属させたい」という要件は、多くの場合「目的のレベルへ新たにスポーンする」という形に置き換えて設計するのが素直です。ブループリントの「Spawn Actor from Class」では OverrideLevel 相当のピンが直接は露出しないことがあるため、レベルを厳密に指定したい場合はC++や、後述のData Layer設計を併用するのが現実的です。なお具体的なピンやノードの有無はバージョンによって異なるため、利用中のエディタで確認してください。

Level Streaming使用時:レベル単位でロード/アンロードする

従来のLevel Streaming構成では、永続レベルに対してサブレベルを動的にロード・アンロードすることで、メモリと描画負荷を制御します。アクター個体ではなくレベル(サブレベル)という箱ごとを出し入れするのが基本です。

サブレベルのロード/アンロード

  • Load Stream Level:指定したサブレベルをロードします。ロード完了で、そのレベルに配置されたアクターがワールドに存在するようになります。
  • Unload Stream Level:指定したサブレベルをアンロードします。そのレベルに属するアクターはワールドから取り除かれます。
  • これらは「Should Block on Load」などの引数で、ロード完了を待つか非同期で進めるかを制御できます。アンロード時にアクターが消えることを前提に、参照の扱いを設計する必要があります。

アクターを別レベルの文脈で扱う実務的アプローチ

「Aサブレベルにあるアクターを、Bサブレベルに属させ直したい」という移送そのものを、ランタイムで直接行う公式の標準ノード/関数は限定的です。エディタ向けには UEditorLevelUtils(Move Actors To Level など)が用意されていますが、これはエディタ拡張・ツール用途であり、出荷ビルドのゲームプレイ中の移送を意図したAPIではありません。実行中のゲームでアクターの所属を切り替えたい場合は、次のような方針が現実的です。

アプローチ概要向いている場面
再スポーン+破棄移送先レベルを OverrideLevel に指定して同等のアクターをスポーンし、元アクターの状態をコピーしてから「Destroy Actor」で元を破棄する。所属レベルそのものを厳密に変えたい場合
参照保持で論理的に管理物理的な所属レベルは変えず、アクターへのObject Referenceを管理クラス(GameInstance/Subsystemなど)で保持し、どのレベルがアンロードされても参照が切れないよう設計する。所属レベルより「生存・参照」を維持したい場合
常駐レベルへ配置レベルをまたいで存在させたいアクターは、最初からアンロードされない永続レベル側に配置・スポーンする。プレイヤーや常駐マネージャ等

「再スポーン+破棄」では、見た目の連続性を保つため、Transform・コンポーネントの状態・所持データなどを明示的に引き継ぐ実装が必要です。アタッチ関係がある場合は、移送前に「Detach from Actor」で切り離し、移送後に「Attach to Actor」で再構築するなど、親子関係の維持も自前で扱います。

World Partition環境:Data Layerとストリーミングソースで制御する

World Partitionを使うプロジェクトでは、サブレベルを手動ロードする代わりに、エンジンが空間グリッドのセル単位でアクターを自動的にストリーミングします。これに加えてData Layerを使うと、空間位置とは別の軸でアクター群のロード/アクティブ状態を制御できます。

  • Data Layer(ランタイム):アクターをエディタ上でData Layerに割り当てておき、ランタイムでそのレイヤーの状態(おおむね「アンロード/ロード済み/アクティブ」に相当する状態)を切り替えます。これにより、特定のアクター群をまとめて出現・退避させられます。
  • ストリーミングソース:プレイヤーなどの位置を基準にセルがロードされます。Data Layerに割り当てたアクターも、空間ロードの設定(Is Spatially Loaded)に従い、原則として対応するセルがストリーミング対象になったときにロードされます。
  • ブループリント制御:Data Layerの状態切り替えはブループリントから行えます。例として、昼夜・クエスト進行・チームなどに応じて、関連アクター群を含むData Layerをまとめて切り替える運用が挙げられます。

World Partitionでは「アクターを別レベルへ移す」という発想よりも、「どのData Layer/セルに属させ、どの条件でロードするか」を設計時に決める方が中心になります。実行中に挙動を変えたい場合は、Data Layerの状態切り替えや、対象アクターの有効・無効、再スポーンの組み合わせで表現します。Data Layerの状態名や空間ロードの細かい挙動はバージョンで差異があるため、公式ドキュメントで利用中のバージョンの仕様を確認してください。

落とし穴と注意点

落とし穴内容と対策
直接移送APIへの期待実行中のゲームで、既存アクターを別レベルへ「そのまま」移し替える標準APIは限定的です。UEditorLevelUtils はエディタ用途です。ランタイムでは再スポーン+破棄や参照保持で代替する前提に立つのが安全です。
参照切れ(ダングリング参照)レベルやData Layerをアンロードすると、そのアクターは破棄され、保持していた参照が無効になります。アクセス前に IsValid 相当のチェックを行い、必要なら常駐側のマネージャで参照を管理します。
座標・状態の引き継ぎ漏れ再スポーン方式では、Transform・速度・所持品・アニメーション状態などが自動では引き継がれません。引き継ぐべき情報を洗い出し、明示的にコピーします。アタッチ関係も再構築が必要です。
ストリーミングのタイミングレベル/セルのロードは非同期で完了が遅延します。ロード完了前に対象アクターへアクセスすると失敗します。完了通知やブロッキングロードの要否を設計に組み込みます。
2系統の取り違えLevel StreamingとWorld Partitionは併用しない設計です。手順やノードを混同すると意図通り動きません。まずプロジェクトがどちらかを確認します。
ネットワーク(マルチプレイ)再スポーンや破棄はレプリケーション対象です。サーバ権限での実行やクライアント側の整合性を考慮しないと、表示の不一致や二重生成が起きやすくなります。

FAQ

Q. ブループリントの「Set Level Instance」ノードで、アクターの所属レベルを変更できますか?

A. 「Level Instance」はレベルをアセットのように配置・再利用するための機能であり、その名称のノードで任意の既存アクターの所属レベルを切り替える、という用途とは異なります。アクターの所属レベルを変えたい場合は、本記事のとおり「移送先レベルを指定したスポーン」や「Data Layer/レベルのロード制御」で設計するのが基本です。具体的なノード名や機能はバージョンで変わるため、利用中のエディタとドキュメントで確認してください。

Q. アクターが現在どのレベルに属しているかを実行中に知る方法はありますか?

A. C++では AActor::GetLevel() でアクターが属する ULevel を取得でき、そこから所属レベルを判別できます。ブループリントでも所属レベルやストリーミング状態を取得する手段が用意されている場合があります。ただし、World Partition環境では「サブレベル」という単位ではなくセル/Data Layerでの管理になるため、確認したい観点(空間セルかData Layerか)に応じて適切なAPIを選ぶ必要があります。

Q. レベルをまたいで存在し続けてほしいアクターは、どう配置すべきですか?

A. アンロードされない永続レベル側に配置・スポーンするのが基本です。World Partitionでは、空間ロードの対象から外す設定(Is Spatially Loaded をオフにする等)や、常時ロードされるData Layerに割り当てる方法が考えられます。プレイヤーや常駐マネージャのように、特定レベルに依存させたくないインスタンスは、最初から「どのレベルにも消されない場所」に置く設計が安全です。

まとめ

UE5で「アクターが属するレベルを動的に変更する」というテーマは、実態としてはスポーン先レベルの制御レベル/Data Layer単位のロード制御の組み合わせで実現します。既存アクターをそのまま別レベルへ移送する標準のランタイムAPIは限定的なため、再スポーン+破棄や参照保持といった実務的アプローチを選びます。まずプロジェクトが従来のLevel StreamingかWorld Partitionかを確認し、参照切れ・状態引き継ぎ・ストリーミングのタイミング・マルチプレイ整合性といった落とし穴に注意してください。ノード名やData Layerの状態仕様はバージョンで差異があるため、最終判断は利用中のバージョンの公式ドキュメントで行うことを推奨します。