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

タイトル: レベルを移動する方法
SEOタイトル: UE5 レベル移動完全ガイド (Open Level / Level Streaming / World Partition / Loading Screen)

この記事の要点
  • 基本: Open Level (By Name) または Open Level (By Object Reference) Blueprint ノード
  • Soft Object Reference (TSoftObjectPtr) で未ロードのレベルを参照 → メモリ節約
  • 広大マップは Level Streaming / World Partition で分割ロード
  • Trigger Box / Streaming Volume を使えば、プレイヤー位置に応じて Sub Level を自動 Load/Unload
  • Open Level は全アクター破棄&新規生成 → ロード画面を挟む必要、Multiplayer 同期に注意

UE5 でレベル(マップ)を切り替える方法

UE5 でレベル間を移動する方法は大きく分けて 2 種類あります:

  1. Open Level:現在のレベルを完全に破棄して新しいレベルを開く(ステージ間移動・タイトル → ゲーム)
  2. Level Streaming / World Partition:大きなマップを分割してロード / アンロード(オープンワールド)

方法 1: Open Level(完全な切替)

Blueprint で実装

Blueprint Graph で右クリック → 「Open Level (by Name)」または「Open Level (by Object Reference)」を配置。

Open Level (By Name) ノード
├── Level Name : Name 型 (例: "L_GameStart")
├── Absolute   : true (デフォルト)
└── Options    : 追加引数 (例: "?Listen" でリッスンサーバ起動)

Open Level (By Object Reference) ノード
├── Level     : World 型 (アセットを直接参照)
├── Absolute  : true
└── Options   : 追加引数

C++ で実装

#include "Kismet/GameplayStatics.h"

// 名前で開く(FName 型)
UGameplayStatics::OpenLevel(this, FName("L_GameStart"));

// オプション付き
UGameplayStatics::OpenLevel(this, FName("L_GameStart"), true, TEXT("?Listen"));

// Soft Object Reference で開く(推奨:誤タイポ防止)
UPROPERTY(EditAnywhere)
TSoftObjectPtr<UWorld> NextLevel;

void AMyActor::TravelToNext()
{
    if (!NextLevel.IsNull())
    {
        FName LevelName = FName(*NextLevel.GetLongPackageName());
        UGameplayStatics::OpenLevel(this, LevelName);
    }
}

By Name と By Object Reference の違い

項目By NameBy Object Reference (Soft)
記述文字列 ("L_Stage1")アセット参照
タイポ耐性低い(実行時エラー)★ コンパイル時に検出
パッケージ移動パス変更で壊れる★ 自動追従
メモリ常に文字列分のみ★ Soft なら未ロード
推奨動的選択(DataTable 等)★ 通常時はこちら

Open Level 時の挙動と注意

  • 全アクターが破棄される(プレイヤーキャラクタ含む)
  • GameInstance だけは跨いで保持される → セーブデータ・プレイヤースコアは GameInstance に
  • ロード中の数秒〜数十秒、画面が固まるように見える → Loading Screen 推奨
  • Streaming Level も自動でアンロードされる
  • Multiplayer 環境ではサーバが ClientTravel / ServerTravel を発行する必要あり

Loading Screen の実装

Open Level は同期処理で画面停止するため、ローディング画面を出すのが定番。MoviePlayerを使うのが公式推奨です。

// GameInstance::OnStart() などで PreLoadScreen / MoviePlayer 連携
#include "MoviePlayer.h"

FLoadingScreenAttributes LoadingScreen;
LoadingScreen.bAutoCompleteWhenLoadingCompletes = true;
LoadingScreen.MinimumLoadingScreenDisplayTime = 2.0f;
LoadingScreen.WidgetLoadingScreen = FLoadingScreenAttributes::NewTestLoadingScreenWidget();

GetMoviePlayer()->SetupLoadingScreen(LoadingScreen);
UGameplayStatics::OpenLevel(this, FName("L_GameStart"));

方法 2: Level Streaming(Sub Level の動的ロード)

大きなマップで「現在地周辺だけロード」したい場合、Persistent Level + Sub Level 構成にして、必要なものだけ Load/Unload します。

Window > Levels から Sub Level を登録

  1. メニュー Window > Levels で Levels パネルを開く
  2. + Add Sub Level で新規 Sub Level 作成 / 既存追加
  3. Streaming Method を Always Loaded / Blueprint / World Composition から選択

Blueprint からロード / アンロード

ノード: Load Stream Level (By Name)
├── Level Name        : "L_SubArea1"
├── Make Visible After Load : true
├── Should Block on Load    : false (非同期)
└── Latent Info (自動)

ノード: Unload Stream Level (By Name)
├── Level Name        : "L_SubArea1"
├── Should Block on Unload  : false
└── Latent Info (自動)

C++ で実装

#include "Kismet/GameplayStatics.h"
#include "Engine/LatentActionManager.h"

FLatentActionInfo LatentInfo;
UGameplayStatics::LoadStreamLevel(this,
    FName("L_SubArea1"),
    true,   // Make Visible After Load
    false,  // Should Block on Load
    LatentInfo);

// アンロード
UGameplayStatics::UnloadStreamLevel(this,
    FName("L_SubArea1"),
    LatentInfo,
    false);

Level Streaming Volume

プレイヤーが Volume の中に入ったら自動で Sub Level がロードされる仕組み。プログラム不要でエディタ配置だけで動作

  1. Place Actors > Volumes > LevelStreamingVolume をシーンに配置
  2. Volume を選択して、Details > Streaming Levels に対象 Sub Level を追加
  3. Sub Level の Streaming Method を Blueprint

方法 3: World Partition (UE5 推奨)

UE5 で導入された新しい大規模ワールド管理。手動の Sub Level 分割が不要になり、エンジンが自動でセル分割&ストリーミング。

  • 新規プロジェクトでは大型マップはWorld Partition で作成がデフォルト
  • Cell Size(例 25600cm = 256m)でエリア分割
  • プレイヤー位置から Loading Range 内のセルを自動ロード
  • HLOD(遠景の簡易版)でセル外も視覚的に表示
  • One File Per Actor (OFPA) で複数人編集も安全

Data Layer での切替

World Partition 内で「時間帯」「ゲーム進行状態」によってアクター群を切り替えたい場合は Data Layer を使います:

1. World Settings > Data Layers から Data Layer Asset 作成
   - 例: "DL_DayScene", "DL_NightScene"
2. シーンのアクターをそれぞれの Data Layer に割り当て
3. Blueprint で Data Layer の状態を切替
   ノード: Set Data Layer Runtime State
     ├── Data Layer : DL_NightScene
     └── State      : Activated / Loaded / Unloaded

Trigger による Level 移動

// プレイヤーが Trigger Box に入ったら次のレベルへ
UCLASS()
class AStageGoalTrigger : public ATriggerBox
{
    GENERATED_BODY()

    UPROPERTY(EditAnywhere)
    TSoftObjectPtr<UWorld> NextLevel;

    virtual void NotifyActorBeginOverlap(AActor* Other) override
    {
        if (Other && Other->IsA(APawn::StaticClass()))
        {
            if (!NextLevel.IsNull())
            {
                FName LevelName = FName(*NextLevel.GetLongPackageName());
                UGameplayStatics::OpenLevel(this, LevelName);
            }
        }
    }
};

現在のレベル名を取得

// C++
FString CurrentLevelName = UGameplayStatics::GetCurrentLevelName(this);
UE_LOG(LogTemp, Log, TEXT("Current Level: %s"), *CurrentLevelName);

// Streaming Level の状態取得
ULevelStreaming* Streaming = UGameplayStatics::GetStreamingLevel(this, FName("L_SubArea1"));
if (Streaming && Streaming->IsLevelLoaded())
{
    UE_LOG(LogTemp, Log, TEXT("Sub level is loaded"));
}

Blueprint ならGet Current Level Nameノード。

Multiplayer (Listen Server / Dedicated Server) での Travel

関数用途
UGameplayStatics::OpenLevelシングル / クライアント側のみ
GetWorld()->ServerTravel("L_Stage2")サーバが全クライアントを連れて移動
APlayerController::ClientTravel個別クライアントの移動
UGameplayStatics::OpenLevel(..., "?Listen")Listen Server として起動

Open Level vs Level Streaming の使い分け

ケース推奨
タイトル画面 → ゲーム本編Open Level + Loading Screen
ステージ 1 クリア → ステージ 2Open Level(完全リセット)
巨大オープンワールドの自動管理★ World Partition
建物の中 / 外で別レベルLevel Streaming(Trigger or Volume)
時間帯切替(朝・昼・夜)Data Layer
Multiplayer のステージ進行ServerTravel

パフォーマンスの注意

  • Open Level は同期処理で固まる → MoviePlayer / Async Loading で隠す
  • 大きな Sub Level の Load は数秒かかる → 事前 Preload を検討
  • 頻繁な Load/Unload はメモリフラグメンテーションの原因 → Volume 範囲を適切に
  • World Partition の Cell Size を小さくしすぎるとオーバーヘッド増加
  • HLOD を必ず生成して、遠景に「何もない」状態を防ぐ

トラブル対処

症状原因対処
Open Level しても何も起きないレベル名のタイポ / パッケージ未登録Soft Object Reference に切替
Sub Level がロード後すぐ消えるMake Visible After Load 未チェックtrue に設定
移動後にプレイヤー位置がおかしいPlayer Start が無い / 複数各レベルに 1 つだけ配置
GameInstance のデータが消える誤って GameMode に持たせているGameInstance に移動
World Partition でアクター見えないLoading Range 不足 / HLOD 未生成World Partition Editor で Build HLODs

FAQ

Q: Open Level と Restart Level の違いは?
A: Open Level は別レベルへの移動、Restart Level は現レベルをリロード。死亡時のリトライ用にはこちら。

Q: World Partition と Sub Level、新規プロジェクトはどちら?
A: UE5 ではWorld Partition が推奨。Sub Level は UE4 からの移行プロジェクトや小規模で OK。

Q: ロード中の進捗バーを表示したい
A: LoadStreamLevel の Latent Info を使うか、AsyncLoadPrimaryAsset の進捗を取得する Custom Loader を組みます。MoviePlayer の Loading Widget で実装するのが定番。