【Unreal Engine】World Partitionとレベルストリーミング入門:必要な場所だけ読み込む

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

広いマップの必要な場所だけを読み込む仕組みを図解。World PartitionとEnable Streaming、Data Layersを整理し、3個のCubeをLevel Streaming Volumeで出し入れする実践から、Blueprintで読み込む方法まで解説します。

宿屋の中に椅子や棚を並べ、隣の建物にも部屋を作る。街が充実するほど、今は訪れていない場所のデータまで抱える量が増えていきます。

そこで考えたいのが、必要な場所だけを読み込む ことです。近づく前に部屋を用意し、十分離れたら片付ける。こうして遊びながらレベルの一部を出し入れする仕組みを、レベルストリーミング と呼びます。

広いマップの中で、プレイヤーの周囲を優先して読み込む模式図

UE5の World Partition も、このストリーミングを行う仕組みの一つです。まず全体像を整理し、後半では三個のCubeを、近づくと現れ、離れると消えるようにしてみます。

この記事でわかること

  • 描画を省くことと、レベルを読み込まないことの違い
  • World Partition・Data Layers・従来のサブレベルの役割
  • Level Streaming Volumeで読み込み範囲を作る手順
  • Blueprintで読み込む最小例と、確認するポイント

Windows版UE5で、Actorの配置を経験した方を想定します。実践はThird Personプロジェクト内に作る練習用レベルで進めます。図はブログ用の模式図です。

Sponsored

見えない物も、読み込まれていることがある

LOD・カリングの記事では、形を簡略化したり、見えない物を描画から外したりしました。カリングされたActorも、レベルに存在すること自体は変わりません。画面外でTickが動いていれば、その処理も続きます。

ロード はデータを読み込み、使えるようにすること。アンロード は、読み込んだレベルを実行中のワールドから外すことです。ストリーミングでは、この出し入れの単位を分けます。

カリングは描画を省き、レベルのアンロードはその�配置物をワールドから外す
調整主に減らしたいもの
LOD・カリング画面を描く仕事
レベルの分割とストリーミング同時に抱える配置物やデータ、開始時に読み込む量

ただし、部屋を一つ外せば、部屋で使った画像もすべて即座にメモリから消える、という関係ではありません。他の部屋と共有しているデータは残ります。まずは どのレベルが必要な間だけ存在するか を確かめ、メモリや処理時間はその後で測ります。

World Partitionとサブレベルを整理する

読み込む単位の作り方には、大きく二つあります。

World Partitionは空間を分割し、従来方式は作成者がサブレベルへ内容を分ける

World Partition では、広いマップを一つのレベルとして編集し、エンジンが空間を読み込み単位へ分けます。広い屋外を歩き回るゲームで、まず検討したい方式です。

従来の方式では、土台となる Persistent Level(永続レベル) に、別ファイルの サブレベル を登録します。部屋の家具だけを一つのサブレベルへ分け、その読み込みをVolumeやBlueprintで制御できます。「永続」は、そのワールドを使っている間の土台という意味で、ゲームを終了しても残るセーブデータとは違います。

やりたいこと候補
広いマップの周囲を読み込むWorld Partition
World Partition内で祭りの飾りや進行後の景色を切り替えるRuntime Data Layers
分けた部屋を、決めた範囲やイベントで出し入れする従来のサブレベル+Volume / Blueprint
タイトルから本編など、別のマップへ移るOpen Level

距離ならWorld Partition、イベントなら従来方式、と二分する必要はありません。 World Partitionにも、イベントで中身を切り替えるData Layersがあります。

World Partitionのレベルでは、従来のLevelsパネルへサブレベルを追加する手順は使えません。後半の実践は、World Partitionを使わない新しい練習レベルで行います。既存マップを変換する必要はありません。

World Partitionは、必要な範囲を選んで読む

分割した一区画を セル、読み込みの中心となるものを Streaming Source と呼びます。通常はプレイヤー側の位置が中心になり、移動に合わせて必要なセルが変わります。

セルの大きさと、Streaming Sourceから読み込む範囲は別の設定

Cell Size は区切りの細かさ、Loading Range は読み込み元からどこまで用意するか、という違いです。セルを小さくすれば常に軽くなるわけではなく、細かな出し入れを管理する仕事も増えます。数値はテンプレートや分割方式によって異なるため、最初は手元の設定を基準にします。

World Partitionの有効化と、Enable Streamingを分ける

「File → New Level → Open World」から作ると、World Partitionを使うレベルになります。World Settingsの「World Partition Setup」で Enable Streaming も確認してください。これは、実行中に範囲を分けて読み込むかどうかの設定です。

World Partition対応でも、このチェックがオフのテンプレートがあります。「World Partitionだから、今も近くだけ読み込んでいる」とは限りません。

World Partitionの仕組みを使うことと、Enable Streamingをオンにすることを分けて確認する

移動が速いゲームでは先を広く読み、瞬間移動では到着先を先に用意する、といった工夫も必要になります。プレイヤー以外の場所へStreaming Sourceを置けるのは、このためです。

エディタで読み込む範囲は、作業のためのもの

World Partitionの大きなマップでは、編集する場所だけ読み込んで作業できます。「Window → World Partition → World Partition Editor」で範囲を選び、右クリックの Load Region from Selection から読み込みます。

これは エディタで作業する範囲 です。プレイ中のLoading Rangeを、この操作で設定しているわけではありません。レベルを開いたときに一部が見えなければ、作業範囲の読み込みやData Layerの表示を確認します。

距離に関係なく残したいActor

配置した管理用Actorなどは、Detailsの Is Spatially Loaded をオフにすると、距離による読み込み対象から外せます。ただし、割り当てたRuntime Data Layerの状態によっては読み込まれません。「オフならあらゆる条件で常駐」とは覚えないでください。

スコアや進行状況をどこに持たせるかは、Game FrameworkGameInstanceも含めて考えます。遠いActor同士を直接参照すると一緒に読み込まれる場合もあるので、何でも常駐Actorへつなぐ設計にはしない方が扱いやすくなります。

Sponsored

Data Layersで、同じ場所の中身を切り替える

昼間の広場に、祭りの時間だけ屋台を出したい。こうした 場所は同じで、中身を変えたい 場面にはData Layersが向いています。Actorをグループへ割り当て、まとめて扱います。

Editor 型は編集作業の整理用、Runtime 型はゲーム中にも状態を変えるためのものです。祭りの開始に合わせて屋台を出すならRuntimeを使います。

Runtimeの状態考え方
Unloaded読み込まない
Loaded読み込むが、表示して参加させる段階ではない
Activated読み込み、表示する状態にする
同じ広場の屋台を、Unloaded・Loaded・Activatedの状態で扱う

Data Layerには、Content Browserに保存する Asset と、そのレベル内で使う Instance があります。名前や種類の定義がAsset、実際にActorを割り当てて初期状態を決める受け皿がInstanceです。

作るときはContent Browserの「Miscellaneous → Data Layer」でAssetを作り、「Window → World Partition → Data Layer Outliner」へドラッグしてInstanceを用意します。Assetを開いてTypeをRuntimeにし、InstanceのInitial Runtime Stateで開始時の状態を選びます。対象Actorを選び、Outliner側の「Add Selected Actors to Selected Data Layers」で割り当てます。

Loadedを使えば、見せる前に準備する構成を作れます。ただし、状態を指定した瞬間に読み込みが終わるわけではありません。Loaded、Activatedを続けて呼ぶだけでは、事前に待ったことにはなりません。空間側の読み込み条件も関係します。

まずはこの役割を押さえ、ここからは、読み込む単位が目で追いやすいサブレベルで出し入れを試します。

実践:近づくと三個のCubeを読み込む

家具を何百個も用意する前に、三個のCubeで仕組みを確かめましょう。床は残したまま、Cubeだけが近づくと現れ、離れると消える状態を作ります。

同じ床の上で、近づくと三個のCubeが現れ、離れると外される

1. 土台と、出し入れする物を分ける

Third Personプロジェクトを開き、「File → New Level → Basic」で新しいレベルを作り、L_StreamPractice として保存します。これはWorld Partitionを使わない練習用レベルです。

World Settingsの「GameMode Override」をテンプレートの BP_ThirdPersonGameMode にし、Player Startを置きます。すでにあれば一個だけ残します。一度Playし、歩けることを先に確認します。

  1. 床を広げ、左右へ十分歩ける場所を作ります。例として基本Cubeを使うなら、位置 (0, 0, -10)、Scale (60, 30, 0.2) にすると、上面がZ=0の床になります。元の床と重ならないよう置き換えます。
  2. Player Startを (-1800, 0, 100) 付近に置き、回転のYawを0にします。Xのプラス方向を向く出発点です。
  3. 「Window → Levels」を開き、「Levels → Create New」で Empty Level を作り、L_Props として保存します。
  4. L_Propsを右クリックし、「Change Streaming Method → Blueprint」にします。Always Loadedにしていると、範囲による出し入れを試せません。
  5. L_Propsを右クリックして Make Current にします。これは「これから置くActorの所属先」を選ぶ操作です。
  6. 「Place Actors → Shapes → Cube」から基本Cubeを三個置きます。位置は (200, 0, 50)(500, 0, 50)(800, 0, 50)、Scaleはすべて1です。

ここで使うCubeは標準の一辺100cmの形状です。Z=50にすると、底が床の高さへ合います。

Persistent Levelは床とPlayer Startを持ち、L_Propsは三個のCubeを持つ

L_Propsの目のアイコンを切り替え、Cubeだけが消え、床とPlayer Startは残る ことを確認します。これが最初の成功です。目のアイコンは編集時の表示確認で、ゲーム中の読み込み設定とは別です。表示を戻し、両方のレベルを保存します。

2. 読み込みを保つ範囲を置く

Levelsで Persistent LevelをMake Current に戻します。「Place Actors」で Level Streaming Volume を検索し、配置して LSV_Props と名付けます。普通のBox Collisionとは別の、レベルの読み込み用Volumeです。

Volume は、ゲーム内の見えない範囲を表すものです。このVolumeでは、プレイヤーの カメラが範囲内にあるか を調べます。身体が入っていても、背後のカメラが外にあれば同じ判定にはなりません。

例としてVolumeの位置を (600, 0, 200)、回転0、Scale各軸1にし、「Brush Settings」の箱の寸法を X=2000、Y=1600、Z=800 にします。X方向では-400から1600までを覆い、三個のCubeと周囲が入ります。

読み込み範囲は小物の周囲と入口側へ余裕を持たせ、背後のカメラも考慮する

実際の部屋では、入口の手前から室内全体まで、カメラが動く範囲を覆います。ドアの所だけを薄く囲うと、部屋へ進んだ瞬間に範囲を抜け、中身をアンロードしてしまいます。

3. VolumeとL_Propsを関連付ける

LSV_PropsのDetailsを、次のようにします。

項目
Streaming UsageLoading and Visibility
Editor Pre Vis Onlyオフ
Disabledオフ

次にLevelsで L_Props を選び、Levelsパネルの虫眼鏡のアイコンから Level Details を開きます。「Streaming Volumes」の + で要素を追加し、LSV_Propsを選びます。「Initially Loaded」と「Initially Visible」はオフにします。

L_PropsのLevel DetailsからLSV_Propsを指定し、Volume側の読み込みと表示を有効にする

これで「この範囲が必要とするレベルはL_Props」と結び付きます。Volume自体はPersistent Levelに残るため、Cubeが消えた後も、次に近づいたことを判断できます。すべて保存します。

4. 外、内、外の順に歩いて確かめる

Playメニューから Standalone Game で起動し、コンソールで stat levels を入力します。レベルの読み込み状態を確認する表示です。コンソールの開き方はstatコマンドの記事を参照してください。

  1. 出発点では、Cubeがまだ表示されていないことを確認します。
  2. Xのプラス方向へ歩きます。カメラがVolumeへ入った後、読み込みが終わると三個が現れます。
  3. Cubeの周囲を歩き、Volume内にいる間は残るか確かめます。
  4. 出発点側へ十分戻り、少し待ちます。Cubeが消え、L_Propsがアンロード側の状態へ変わるか確認します。

stat levels には途中の状態も表示されます。一瞬の色だけで判断せず、実際の表示と、状態が落ち着いた後の両方 を見ます。外へ出た瞬間に消えなくても、要求から処理までには時間があります。

うまくいかないこと確認する場所
最初からCubeが残るL_PropsがAlways Loadedになっていないか、初期読み込み、開始時のカメラ位置
近づいても出ないStreaming Volumesの関連付け、Disabled、Editor Pre Vis Only
床まで消える床をL_Propsへ置いていないか。LevelsでPersistent Levelを右クリックし、Move Selected Actors to Levelで移す
室内で消えるカメラがVolumeを抜けていないか。範囲を広げる
Levelsで操作できない開いているのがWorld Partitionのレベルではないか

三個の出し入れを確認できたら、L_PropsのCubeを家具や小物へ置き換えられます。まず範囲の設計を確かめ、その後で中身を増やすと原因を追いやすくなります。

Sponsored

Blueprintで読み込む場合

イベントが起きたときに読み込む場合は、Load Stream Level を使います。同じL_Propsを使って、ゲーム開始時に一度だけ読み込む最小例を試せます。

先ほどのL_StreamPracticeを「Save Current Level As」で L_StreamBlueprint として保存します。このコピーで、L_PropsのLevel Detailsにある Streaming Volumesの関連付けを外します。同じレベルをVolumeとBlueprintの両方から制御すると、意図しない出し入れにつながります。

L_Propsの方式はBlueprint、Initially LoadedとInitially Visibleはオフのままです。上部ツールバーのBlueprintsメニューから「Open Level Blueprint」を選び、L_StreamBlueprintの Level Blueprint で次をつなぎます。

  1. Event BeginPlayから Load Stream Level (by Name) へ実行線をつなぎます。
  2. Level Nameへ L_Props、Make Visible After Loadをオン、Should Block on Loadをオフにします。
  3. Completed からPrint Stringへつなぎ、文字を Props loaded にします。
BeginPlayからL_Propsを読み込み、CompletedからPrint Stringへ進む

Compileして保存し、Standaloneで起動します。今度は近づかなくてもCubeが現れ、通知が出れば、開始時の処理から読み込めています。Level Nameの綴りに誤りがないか、実際のCubeと stat levels も合わせて確かめます。

Load Stream Levelは レイテントノード、つまり完了まで時間がかかる処理を扱うノードです。Completedは、その後へ進むための出力です。Make Visible After Loadは「読み込んだ後に表示するか」を選びます。

Should Block on Load をオンにすると、読み込み完了を待つためにゲームの進行が止まることがあります。今回のように歩きながら準備する処理ではオフにします。ただし、オフでも初期化などの仕事は残るため、引っかかりが完全になくなるわけではありません。

取り外す側には Unload Stream Level があります。実際の出入りへ応用するときは、プレイヤーが室内に残っていないことと、前の要求が完了したことを確認してから呼びます。入口のEnd Overlapへそのままつなぐだけでは、部屋に進んだときまで消してしまいます。

動いた後は、読み込みの間に注目する

出し入れが動いたら、次は「必要な時刻に間に合うか」を見ます。入口へ来てから家具が現れるなら、Volumeを入口の手前へ広げて先に読み始めます。カメラを回したときにも、空の部屋が見えないか確認しましょう。

入口の直前で読むと間に合わないことがあり、手前から準備する範囲を設ける
確かめたいこと確認方法
必要な間だけ読み込まれているかstat levels と実際の出入り
境界で止まったように感じないか歩く、走る、向きを変える操作を繰り返す
どの処理に時間がかかるかstat unit、必要ならUnreal Insights
メモリの変化同じ条件の実行で、読み込み前後と時間経過を比較

PIEは切り替え位置を試すのに便利ですが、エディタがすでにデータを持っているため、読み込み時間が実際と違います。Standaloneでも確認し、最終的にはパッケージ化したゲームを対象の環境で動かします。

Cube三個では、性能差がほとんど出なくても自然です。家具を増やした比較でも、「一棟で何ms、十棟なら十倍」とは計算できません。描画される量、共有アセット、カメラの向き、読み込み時の仕事がそれぞれ関係します。

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

OFPAは、編集時の保存を分ける仕組み

One File Per Actor(OFPA) は、配置したActorの情報を個別ファイルへ保存する方式です。World Partitionでは標準で使われ、別々のActorを編集する人同士が、同じレベルファイルを変更する機会を減らせます。

一つのレベルファイルにまとめる保存と、Actorごとに分けるOFPAの違い

これは主にエディタとソース管理の話です。OFPAはWorld Partition以外でも利用でき、パッケージ化時にはActorのデータがレベル側へまとめられます。__ExternalActors__ などの管理対象も含め、Git管理の記事で確認してください。

遠景を残すHLODは、設定してビルドする

HLOD は、複数の配置物をまとめた簡略な表現を遠景に使う仕組みです。元の細かなセルが読み込まれていないときも、街並みの輪郭を残す用途があります。

World Partitionを有効にしただけで、すべての遠景が完成するわけではありません。対象のHLOD Layerを設定し、HLODをビルドする必要があります。通常のLODが一個のモデルの細かさを変えるのに対し、HLODは複数の配置物をまとめて扱います。

消えたActorの状態を、どこへ残すか

部屋のActorをアンロードすると、そのActorの変数を次の訪問までそのまま使えるとは限りません。開けた宝箱などは、GameInstanceセーブデータへ必要な状態を記録し、読み込み直したときに反映します。

メモリも、不要なデータを回収する ガベージコレクション の時刻や、他からの参照に左右されます。アンロード後に値が下がらない理由を、回収待ちだけと決めつけず、必要ならUnreal Insightsで調べます。

まずは部屋の小物だけを分け、近づく前に準備できるか試してみてください。どこで読み始め、どこまで残すかを歩いて確かめると、自分のマップに必要な範囲が見えてきます。

まとめ

  • 「描かない」ことと「読み込まない」ことは別物
  • 広い世界はWorld Partitionが自動で分け、区画ごとの出し分けはData Layersが担当する
  • Level Streaming Volumeなら、範囲へ入ったときに読み込める
  • Blueprintで読み込むときは、完了を待ってから次へ進める

選ぶときの問いかけは、「そこへ歩いて行けるか、別の場面へ切り替わるか」 です。歩いて行けるならStreaming、切り替わるなら Open Levelでのレベル遷移 です。

描画側を減らす話は LODとカリング にあります。

参考:World PartitionData LayersLevel Streaming VolumesVolumeの設定手順Load Stream Level

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