ChunkDownloader をゲームに実装する

ローカルホスト ウェブサイトをセットアップする

Choose your operating system:

Windows

macOS

Linux

前提トピック

このページは以下のトピックへの知識があることを前提にしています。まず以下のトピックの内容についてご確認をお願いします。

ChunkDownloader Unreal Engine のパッチ適用ソリューションです。これはアセットをリモート サービスからダウンロードし、メモリにマウントしてゲーム内で使用します。これにより、アップデートやアセットを簡単に提供することができます。このガイドでは、プロジェクトに ChunkDownloader を実装する方法を説明します。このガイドを読み終えると、次のことができるようになります。

  • ChunkDownloader プラグインを有効化してプロジェクトの依存関係に追加します。

  • チャンクにコンテンツを編成して .pak ファイルにパッケージ化し、ダウンロード用のマニフェスト ファイルを準備します。

  • ChunkDownloader をゲームのコードに実装し、リモート .pak ファイルをダウンロードします。

  • マウント済みの .pak ファイルからコンテンツに安全にアクセスします。

1. 必要な設定と推奨されるアセット

先に進む前に次のガイドを確認し、それぞれの手順に従ってください。

これらのガイドでは、プロジェクトに ChunkDownloader プラグインを追加する方法、アセットにチャンク化のスキームを設定する方法、それらをローカル テスト サーバーに配布する方法を説明しています。確認するには、サンプル プロジェクトが「 PatchingDemo 」という名前で、次のように構成する必要があります。

  1. Blank テンプレート をベースにして C++ プロジェクト を使用します。

  2. ChunkDownloader プラグインを [Plugins (プラグイン)] メニューで有効にします。

  3. [Project Settings (プロジェクト設定)] > [Project (プロジェクト)] > [Packaging (パッケージ化)] [Use Pak File (pak ファイルを使用)] [Generate Chunks (チャンクの生成)] の両方を有効にします。

  4. Paragon の Boris Crunch Khaimera アセットをプロジェクトに追加します。

    • これらのアセットは、 Unreal マーケットプレイス から無料でダウンロードできます。

    • 個別のフォルダに分けられている限り、どのアセットも使用することができます。

  5. 3 つのキャラクターのフォルダにはそれぞれ Primary Asset Label が適用され、次の チャンク ID が割り振られています。

    フォルダ

    チャンク ID

    ParagonBoris

    1001

    ParagonCrunch

    1002

    ParagonKhaimera

    1003

  6. コンテンツはクック済みで、上述のチャンク ID ごとに .pak ファイルがあります。

  7. BuildManifest-Windows.txt 」という名前の マニフェスト ファイル に、次の情報が含まれています。

    [REGION:codetitlebar]
    BuildManifest-Windows.txt
    [/REGION]
    $NUM_ENTRIES = 3
    $BUILD_ID = PatchingDemoKey
    $pakchunk1001-WindowsNoEditor.pak   922604157   ver 1001    /Windows/pakchunk1001-WindowsNoEditor.pak
    $pakchunk1002-WindowsNoEditor.pak   2024330549  ver 1002    /Windows/pakchunk1002-WindowsNoEditor.pak
    $pakchunk1003-WindowsNoEditor.pak   1973336776  ver 1003    /Windows/pakchunk1003-WindowsNoEditor.pak

    各チャンクのすべてのフィールドはタブ区切りで同じ行にある必要があります。そうでない場合は正しくパスされなくなります。

  8. .pak ファイルとマニフェスト ファイルが、ローカルでホスティングされているウェブサイトに配布されています。この設定方法の説明は、「 ChunkDownloader のマニフェストとアセットをホスティングする 」を参照してください。

  9. プロジェクトの DefaultGame.ini ファイルには、 CDN URL が次のように定義されています。

    [REGION:codetitlebar]
    DefaultGame.ini
    [/REGION]
    [/Script/Plugins.ChunkDownloader PatchingDemoLive]
    +CdnBaseUrls=127.0.0.1/PatchingDemoCDN

2. ChunkDownloader を初期化およびシャットダウンする

ChunkDownloader は FPlatformChunkInstall インターフェースの実装です。これは、ゲームが実行されているプラットフォームによって異なるモジュールを区別なくロードできる様々なインターフェースの 1 つです。すべてのモジュールは使用する前にロードおよび初期化し、シャットダウンしてクリーンナップする必要があります。

ChunkDownloader を使用してこれを行う最も簡単な方法は、カスタムの GameInstance クラスを使用する方法です。GameInstance には関連付けが可能な適切な初期化とシャットダウン関数が備わっているだけでなく、ゲームの実行中は ChunkDownloader への継続的なアクセスも提供されます。次の手順でこの実装について説明します。

  1. 新規の C++ クラス を、ベース クラスとして GameInstance を使用して作成します。名前を「 PatchingDemoGameInstance 」にします。

    クリックして画像を拡大します。

  2. PatchingDemoGameInstance.h を IDE で開きます。public ヘッダの下に、次の関数のオーバーライドを追加します。

    [REGION:codetitlebar]
    PatchingDemoGameInstance.h
    [/REGION]
    public:
    /** Overrides */
        virtual void Init() override;
        virtual void Shutdown() override;

    Init 関数はゲームの起動時に実行されるため、ChunkDownloader を初期化するのに理想的です。同様に、 Shutdown 関数はゲームの停止時に実行されるため、ChunkDownloader モジュールをシャットダウンするのに使用できます。

  3. PatchingDemoGameInstance.h で、protected ヘッダの下に次の変数宣言を追加します。

    [REGION:codetitlebar]
    PatchingDemoGameInstance.h
    [/REGION]
    protected:
    //Tracks Whether or not our local manifest file is up to date with the one hosted on our website
    bool bIsDownloadManifestUpToDate;
  4. PatchingDemoGameInstance.cpp を開きます。次の #include をファイルの #include "PatchingDemoGameInstance.h" のすぐ下に追加します。

    [REGION:codetitlebar]
    PatchingDemoGameInstance.cpp
    [/REGION]
    #include "PatchingDemoGameInstance.h"
    
    #include "ChunkDownloader.h"
    #include "Misc/CoreDelegates.h"
    #include "AssetRegistryModule.h"

    これにより ChunkDownloader や、アセットやデリゲートを管理するいくつかの便利なツールにアクセスできるようになります。

  5. PatchingDemoGameInstance.h で、 protected ヘッダの下に次の関数を宣言します。

    [REGION:codetitlebar]
    PatchingDemoGameInstance.h
    [/REGION]
    void OnManifestUpdateComplete(bool bSuccess);
  6. PatchingDemoGameInstance.cpp で、 OnManifestUpdateComplete の実装を次のように作成します。

    [REGION:codetitlebar]
    PatchingDemoGameInstance.cpp
    [/REGION]
    void UPatchingDemoGameInstance::OnManifestUpdateComplete(bool bSuccess)
    {
        bIsDownloadManifestUpToDate = bSuccess;
    }

    この関数は、マニフェストの更新が終了する時に非同期のコールバックとして使用されます。

  7. PatchingDemoGameInstance.cpp で、 Init 関数の実装を次のように作成します。

    [REGION:codetitlebar]
    PatchingDemoGameInstance.cpp
    [/REGION]
    void UPatchingDemoGameInstance::Init()
    {
        Super::Init();
    
        const FString DeploymentName = "PatchingDemoLive";
        const FString ContentBuildId = "PatcherKey";
    
        // initialize the chunk downloader
        TSharedRef<FChunkDownloader> Downloader = FChunkDownloader::GetOrCreate();
        Downloader->Initialize("Windows", 8);
    
        // load the cached build ID
        Downloader->LoadCachedBuild(DeploymentName);
    
        // update the build manifest file
        TFunction<void(bool bSuccess)> UpdateCompleteCallback = [&](bool bSuccess){bIsDownloadManifestUpToDate = bSuccess; };
        Downloader->UpdateBuild(DeploymentName, ContentBuildId, UpdateCompleteCallback);
    }

    このコードの機能をまとめます。

    1. 関数は DeploymentName ContentBuildID を定義して、 DefaultGame.ini で使用される値と一致させます。今使用しているものはテスト用の固定値ですが、フルビルドでは HTTP リクエストを使用して ContentBuildID をフェッチします。関数は、これらの変数の情報を使用して、ウェブサイトにマニフェストをリクエストします。

    2. 関数は FChunkDownloader::GetOrCreate を呼び出し、ChunkDownloader を設定してその参照を取得すると、それを TSharedRef にストアします。これは、このプラットフォーム インターフェースまたは同様のプラットフォーム インターフェースへの参照を取得する最も望ましい方法です。

    3. 関数は目的のプラットフォーム名、この場合は「Windows」を使用して FChunkDownloader::Initialize を呼び出します。このサンプルでは、TargetDownloadsInFlight の値は 8 です。この値で、ChunkDownloader が一度に処理するダウンロードの最大数を設定します。

    4. 関数は DeploymentName を使用して FChunkDownloader::LoadCachedBuild を呼び出します。これは、ディスク上にすでにダウンロードしたファイルがあるかを確認します。それらのファイルが最新のマニフェストに更新されている場合は、ChunkDownloader の再ダウンロードをスキップすることができます。

    5. 関数は FChunkDownloader::UpdateBuild を呼び出して、マニフェスト ファイルの更新バージョンをダウンロードします。

      • システムは、このようにしてまったく新しい実行ファイルを必要とせずに更新パッチをサポートします。

      • UpdateBuild DeploymentName ContentBuildID を、操作が成功したか失敗したかを出力するコールバックと一緒に取得します。

      • また、 OnManifestUpdateComplete を使用して bIsDownloadManifestUpToDate を設定することにより、GameInstance でこのフェーズのパッチ適用が終了したことをグローバルに認識することができます。

    これらの手順に従うことで ChunkDownloader が初期化され、コンテンツをダウンロードする準備が整っていることを確認し、他の関数にマニフェストの状態を通知します。

3. Pak ファイルをダウンロードする

ChunkDownloader の適切な初期化およびシャットダウン関数ができたので、この .pak ダウンロード機能を公開することができます。

  1. PatchingDemoGameInstance.h で、次のように GetLoadingProgress の関数宣言を追加します。

    [REGION:codetitlebar]
    PatchingDemoGameInstance.h
    [/REGION]
    UFUNCTION(BlueprintPure, Category = "Patching|Stats")
    void GetLoadingProgress(int32& FilesDownloaded, int32& TotalFilesToDownload, float& DownloadPercent, int32& ChunksMounted, int32& TotalChunksToMount, float& MountPercent) const;
  1. PatchingDemoGameInstance.cpp で、次のように GetLoadingProgress 関数の実装を作成します。

    [REGION:codetitlebar]
    PatchingDemoGameInstance.cpp
    [/REGION]
    void UPatchingDemoGameInstance::GetLoadingProgress(int32& BytesDownloaded, int32& TotalBytesToDownload, float& DownloadPercent, int32& ChunksMounted, int32& TotalChunksToMount, float& MountPercent) const
    {
        //Get a reference to ChunkDownloader
        TSharedRef<FChunkDownloader> Downloader = FChunkDownloader::GetChecked();
    
        //Get the loading stats struct
        FChunkDownloader::FStats LoadingStats = Downloader->GetLoadingStats();
    
        //Get the bytes downloaded and bytes to download
        BytesDownloaded = LoadingStats.BytesDownloaded;
        TotalBytesToDownload = LoadingStats.TotalBytesToDownload;
    
        //Get the number of chunks mounted and chunks to download
        ChunksMounted = LoadingStats.ChunksMounted;
        TotalChunksToMount = LoadingStats.TotalChunksToMount;
    
        //Calculate the download and mount percent using the above stats
        DownloadPercent = (float)BytesDownloaded / (float)TotalBytesToDownload;
        MountPercent = (float)ChunksMounted / (float)TotalChunksToMount;
    }
  2. PatchingDemoGameInstance.h で、#include の下に次のダイナミック マルチキャスト デリゲートを追加します。

    [REGION:codetitlebar]
    PatchingDemoGameInstance.h
    [/REGION]
    DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FPatchCompleteDelegate, bool, Succeeded);

    このデリゲートは Boolean を出力します。これによりパッチのダウンロード操作が成功したかどうかがわかります。デリゲートは通常、ファイルのダウンロードやインストールなどの非同期操作に応答するために使用されます。

  3. UPatchingDemoGameInstance クラスで、 public ヘッダの下に次のデリゲート宣言を追加します。

    [REGION:codetitlebar]
    PatchingDemoGameInstance.h
    [/REGION]
    /** Delegates */
    
    /** Fired when the patching process succeeds or fails */
    UPROPERTY(BlueprintAssignable, Category="Patching");
    FPatchCompleteDelegate OnPatchComplete;

    これにより、パッチ適用操作の完了時にブループリントに接続する場所が用意されます。

  4. protected ヘッダの下に、次のような ChunkDownloadList の宣言を追加します。

    [REGION:codetitlebar]
    PatchingDemoGameInstance.h
    [/REGION]
    /** List of Chunk IDs to try and download */
    UPROPERTY(EditDefaultsOnly, Category="Patching")
    TArray<int32> ChunkDownloadList;

    このリストを使用して、後でダウンロードする必要があるチャンク ID をすべて取得します。開発設定では、必要に応じてこれをアセットのリストで初期化しますが、テスト目的の場合はこのままデフォルトで公開します。それにより、ブループリント エディタを使用して入力することができます。

  5. public ヘッダの下に、次のように PatchGame の宣言を追加します。

    [REGION:codetitlebar]
    PatchingDemoGameInstance.h
    [/REGION]
    /** Starts the game patching process.Returns false if the patching manifest is not up to date. */
    UFUNCTION(BlueprintCallable, Category = "Patching")
    bool PatchGame();

    この関数により、ブループリントで公開されたパッチ適用処理を開始するための方法が提供され、成功したかしないかを示す Boolean が返されます。これはダウンロード管理やその他の非同期タスクの代表的な手法です。

  6. protected ヘッダの下に、次の関数宣言を追加します。

    [REGION:codetitlebar]
    PatchingDemoGameInstance.h
    [/REGION]
    /** Called when the chunk download process finishes */
    void OnDownloadComplete(bool bSuccess);
    
    /** Called whenever ChunkDownloader's loading mode is finished*/
    void OnLoadingModeComplete(bool bSuccess);
    
    /** Called when ChunkDownloader finishes mounting chunks */
    void OnMountComplete(bool bSuccess);

    これらを使用して、ダウンロード処理での非同期コールバックに応答します。

  7. PatchingDemoGameInstance.cpp で、次のように OnDownloadComplete OnLoadingModeBegin の実装を追加します。

    [REGION:codetitlebar]
    PatchingDemoGameInstance.cpp
    [/REGION]
    void UPGameInstance::OnLoadingModeComplete(bool bSuccess)
    {
        OnDownloadComplete(bSuccess);
    }
    
    void OnMountComplete(bool bSuccess)
    {
        OnPatchComplete.Broadcast(bSuccess);
    }

    OnLoadingModeComplete は OnDownloadComplete に渡され、後の手順でチャンクのマウントに進みます。OnMountComplete はすべてのチャンクがマウントを完了し、コンテンツを使用する準備が整っていることを示します。

  8. PatchingDemoGameInstance.cpp で、次のように PatchGame の実装を追加します。

    [REGION:codetitlebar]
    PatchingDemoGameInstance.cpp
    [/REGION]
    bool UPGameInstance::PatchGame()
    {
        // make sure the download manifest is up to date
        if (bIsDownloadManifestUpToDate)
        {
            // get the chunk downloader
            TSharedRef<FChunkDownloader> Downloader = FChunkDownloader::GetChecked();
    
            // report current chunk status
            for (int32 ChunkID :ChunkDownloadList)
            {
                int32 ChunkStatus = static_cast<int32>(Downloader->GetChunkStatus(ChunkID));
                UE_LOG(LogTemp, Display, TEXT("Chunk %i status: %i"), ChunkID, ChunkStatus);
            }
    
            TFunction<void (bool bSuccess)> DownloadCompleteCallback = [&](bool bSuccess){OnDownloadComplete(bSuccess);};
            Downloader->DownloadChunks(ChunkDownloadList, DownloadCompleteCallback, 1);
    
            // start loading mode
            TFunction<void (bool bSuccess)> LoadingModeCompleteCallback = [&](bool bSuccess){OnLoadingModeComplete(bSuccess);};
            Downloader->BeginLoadingMode(LoadingModeCompleteCallback);
            return true;
        }
    
        // we couldn't contact the server to validate our manifest, so we can't patch
        UE_LOG(LogTemp, Display, TEXT("Manifest Update Failed.Can't patch the game"));
    
        return false;
    
    }

    この関数は次の手順を実行します。

    1. 最初に、マニフェストが最新かどうかを確認します。ChunkDownloader を初期化していないためにマニフェストの最新版を取得できていない場合、 bIsDownloadManifestUpToDate が false となり、この関数は false を返します。これは、パッチ適用の開始に失敗したことを示しています。

    2. 次に、パッチ適用処理が継続する場合は、関数が ChunkDownloader への参照を取得します。ダウンロード リストを反復処理して、各チャンクの状態を確認します。

    3. 2 つのコールバックが定義されます。

      • DownloadCompleteCallback は、チャンクごとにダウンロードが完了すると呼び出され、それぞれがダウンロードに成功したか失敗した時にメッセージを出力します。

      • LoadingModeCompleteCallback は、すべてのチャンクがダウンロードされると実行されます。

    4. 関数は FChunkDownloader::DownloadChunks を呼び出して、 ChunkDownloadList にリスト表示されている必要なチャンクのダウンロードを開始します。この関数を呼び出す前に、このリストに必要なチャンク ID が入力されている必要があります。また、 DownloadCompleteCallback も渡されます。

    5. 関数は、先ほど定義したコールバックを使用して FChunkDownloader::BeginLoadingMode を呼び出します。

      • Loading Mode にすると、ChunkDownloader はダウンロード状態の監視を開始します。

      • チャンクは Loading Mode を呼び出さずにバックグラウンドで受動的にダウンロードできますが、使用することでダウンロード Stats が出力され、ユーザーがダウンロードの進捗をトラッキングできる UI を作成することができます。

      • チャンクのバッチ全体がダウンロードされる時に、コールバック関数を使用して特定の機能を実行することもできます。

  9. PatchingDemoGameInstance.cpp で、次のように OnDownloadComplete の実装を追加します。

    [REGION:codetitlebar]
    PatchingDemoGameInstance.cpp
    [/REGION]
    void UPatchingDemoGameInstance::OnDownloadComplete(bool bSuccess)
    {
    if (bSuccess)
        {
            UE_LOG(LogTemp, Display, TEXT("Download complete"));
    
            // get the chunk downloader
            TSharedRef<FChunkDownloader> Downloader = FChunkDownloader::GetChecked();
    
            FJsonSerializableArrayInt DownloadedChunks;
    
            for (int32 ChunkID : ChunkDownloadList)
            {
                DownloadedChunks.Add(ChunkID);
            }
    
            //Mount the chunks
            TFunction<void(bool bSuccess)> MountCompleteCallback = [&](bool bSuccess){OnMountComplete(bSuccess);};
            Downloader->MountChunks(DownloadedChunks, MountCompleteCallback);
    
            OnPatchComplete.Broadcast(true);
    
        }
        else
        {
    
            UE_LOG(LogTemp, Display, TEXT("Load process failed"));
    
            // call the delegate
            OnPatchComplete.Broadcast(false);
        }
    }

    これも複雑な関数のため、これから細かく説明します。これは、ユーザーのデバイスに .pak ファイルのダウンロードが成功すると実行されます。

    1. 最初に、ChunkDownloader への参照を取得します。

    2. 次に、関数は Json 配列を設定し、 ChunkDownloadList の情報を入力します。これは、リクエストの作成に使用されます。

    3. 関数は MountCompleteCallback を使用して、パッチが正常に適用されたかどうかを出力します。

    4. 関数は Json リストと MountCompleteCallback を使用して ChunkDownloader::MountChunks を呼び出し、ダウンロードされたチャンクのマウントを開始します。

    5. ダウンロードに成功すると、関数は OnPatchComplete デリゲートを値 true でアクティベートします。ダウンロードに失敗すると、値 false でアクティベートします。 UE_LOG は失敗の場所に応じてエラー メッセージを出力します。

4. パッチ適用のゲーム モードを設定する

パッチ適用プロセスを開始するために、レベルと、PatchGame を呼び出して画面にパッチ適用 Stats を出力するためのゲーム モードを作成することができます。

  1. Unreal Editor で、「 Blueprints 」フォルダを コンテンツ ブラウザ に新規作成します。次に、ベース クラスとして PatchingDemoGameInstance を使用して 新しいブループリント を作成します。

    クリックして画像を拡大します。

    新しいブループリント クラスの名前を「 CDGameInstance 」にします。

    クリックして画像を拡大します。

    このブループリントを使用することで、設定の編集とチャンクのダウンロード プロセスのトラッキングによりアクセスしやすくなります。

  2. 新しく Game Mode ブループリントを「 PatchingGameMode 」という名前で作成します。

    PatchingGameMode.png

  3. Maps 」フォルダを作成し、次に 2 つの新規レベルを「 PatchingDemoEntry 」と「 PatchingDemoTest 」という名前で作成します。Entry レベルは空のマップをベースに、Test レベルはデフォルトのマップをベースにする必要があります。

    クリックして画像を拡大します。

  4. PatchingDemoEntry [World Settings (ワールドセッティング)] で、 [GameMode Override] [PatchingGameMode] に設定します。

    クリックして画像を拡大します。

  5. [Project Settings (プロジェクト設定)] を開いて [Project] > [Maps & Modes] に移動します。次のパラメータを設定します。

    クリックして画像を拡大します。

    ID

    パラメータ

    1

    Game Instance Class

    CDGameInstance

    2

    Editor Startup Map

    PatchingDemoTest

    3

    Game Default Map

    PatchingDemoEntry

  6. CDGameInstance ブループリント エディタ で開きます。 [Details (詳細)] パネルで 3 つのエントリを [Chunk Download List] に追加し、それぞれの値を 1001、1002、1003 と入力します。これらは 3 つの .pak ファイルのチャンク ID です。

    ChunkDownloadList.png

  7. PatchingGameMode ブループリント エディタ で開き、 EventGraph に移動します。

  8. Get Game Instance ノードを作成し、次にそれを CDGameInstance にキャストします。

  9. [As CDGameInstance] をクリックしてドラッグし、次に Promote to Variable をクリックしてゲーム インスタンスへの参照を作成します。新規変数の Current Game Instance を呼び出します。

  10. Set Current Game Instance の出力ピンをクリックしてドラッグし、 Patch Game への呼び出しを作成します。

  11. Patch Game Return Value をクリックしてドラッグし、次に Promote to Variable をクリックして値をストアする Boolean を作成します。新規変数の Is Patching In Progress を呼び出します。

    クリックして画像を拡大します。

  12. Get Current Game Instance ノードを作成し、次にその出力ピンをクリックしてドラッグし、 Get Patch Status への呼び出しを作成します。

  13. Get Patch Status Return Value ピンをクリックしてドラッグし、 Break PatchStats ノードを作成します。

  14. Tick イベントからクリックしてドラッグし、新しい Branch ノードを作成します。 Is Patching In Progress をその Condition 入力にアタッチします。

  15. Branch ノードの True ピンをクリックしてドラッグし、 Print String ノードを作成します。 BuildString (float) を使用して、 Break PatchStats ノードの Download Percent を出力します。この手順を、 Mount Percent にも繰り返します。

    クリックして画像を拡大します。

  16. Print String ノードから Branch ノードを作成し、次に AND ノードを作成して Condition ピンに接続します。

  17. Greater Than or Equal To ノードを作成して Download Percent 1.0 以上かどうかを確認し、次に同じ設定を Mount Percent にも行います。それら両方を AND ノードに接続します。ちらの条件も true の場合、 Open Level を使用して PatchingGameTest レベルを開きます。

    クリックして画像を拡大します。

これで、ゲームを実行すると Entry マップが開き、 ChunkDownloader が実行され、チャンク ダウンロード リストに載っているチャンクのダウンロードおよびマウンティングの進捗が出力されます。ダウンロードが完了すると、テスト マップに遷移します。

これを Play In Editor を使用して実行しようとすると、ダウンロードが開始されません。ChunkDownloader はパッケージ化されたビルドでテストする必要があります。

5. ダウンロードしたコンテンツを表示する

キャラクター メッシュを表示するには、それらへの参照を取得する必要があります。これは、アセットを使用する前にロードされているか検証する必要があるため、 Soft Object References が必要になります。このセクションでは簡単な例を使用して、アクタのスポーン方法とソフトリファレンスからスケルタル メッシュを埋める方法について説明します。

  1. Open the レベルを開き、次に レベル ブループリント を開きます。

  2. 新規変数を Meshes という名前で作成します。

    • [Variable Type (変数の型)] には [Skeletal Mesh (スケルタル メッシュ)] を選択します。

    • タイプのリストでエントリにマウスオーバーして [Soft Object Reference] を選択します。これにより、変数の色が青から黄緑色に変わります。

    クリックして画像を拡大します。

Soft Object References は不明瞭なアセットを安全に参照することができるスマート ポインタの一種です。これを使用して、メッシュ アセットを使用する前に、メッシュ アセットがロードされていて使用可能になっているかを確認できます。

  1. [Meshes] [Variable Type] の隣にあるアイコンをクリックし、 [Array] に変更します。ブループリントをコンパイルして変更を適用します。

    クリックして画像を拡大します。

  2. [Meshes] [Default Value] に 3 つのエントリを追加し、 Boris Crunch 、および Khaimera のスケルタル メッシュを選択します。

    クリックして画像を拡大します。

  3. レベルの イベントグラフ で、 BeginPlay イベントをクリックしてドラッグし、 For Each Loop を作成して Meshes の配列に接続します。

  4. For Each Loop Array Element] ピンをクリックしてドラッグし、 Is Valid Soft Object Reference ノードを作成します。 Loop Body から ブランチ を作成し、 Return Value に接続します。

  5. Spawn Actor From Class ノードを作成して Branch ノードの True ピンに接続します。 Class Skeletal Mesh Actor を選択します。

  6. For Each Loop Array Index をクリックしてドラッグし、 Integer x Float ノードを作成します。浮動小数値を 192.0 に設定します。

  7. Integer x Float ノードの Return Value からクリックしてドラッグし、 Vector x Float ノードを作成してベクターの値を (1.0, 0.0, 0.0) に指定します。

    • これにより、For Each loop を通過するたびに、座標が原点から 192 単位離れます。これにより、スポーン時にメッシュごとにいくらかの空間が与えられます。

  8. 前述の手順のベクターを Make Transform ノードの Location として使用し、次に Return Value Spawn Actor ノードの Spawn Transform 入力に接続します。

  9. Spawn Actor ノードの Return Value をクリックしてドラッグし、 Skeletal Mesh Component への参照を取得します。それを使用して Set Skeletal Mesh を呼び出します。

  10. Array Element ノードをクリックしてドラッグし、 Resolve Soft Object Reference ノードを作成します。このノードの出力を Set Skeletal Mesh New Mesh 入力ピンに接続します。

    クリックして画像を拡大します。

  11. レベル内の Player Start (-450, 0.0, 112.0) に移動します。

    クリックして画像を拡大します。

  12. 作業を保存してブループリントをコンパイルします。

レベルをロードすると、キャラクターごとのスケルタル メッシュがスポーンします。ソフト オブジェクト リファレンスが機能しない場合、各キャラクターのチャンクがマウントされていないため、アセットを使用することができず、スポーンしません。

CharactersSpawned.png

.pak ファイル内に含まれているアセットを参照する時は、常に標準のハード リファレンスの代わりにソフト オブジェクト リファレンスを使用してください。ハード リファレンスを使用すると、チャンク化スキームが壊れます。

6. ゲームをテストする

最後に、プロジェクトをスタンドアローン ビルドでテストする必要があります。Pak のマウンティングは PIE モードでは機能しません。そのため、これはパッチ適用機能をテストするための必要な手順です。

  1. プロジェクトをパッケージ化します。

  2. .pak ファイルとマニフェストを IIS テスト ウェブサイト の対応するフォルダにコピーします。

  3. IIS プロセスとウェブサイトの両方が実行中であることを確認します。

  4. パッケージ化された実行ファイルを実行します。

最終結果

画面の左上にパッチ適用出力が表示されている黒い画面を確認することができます。次に、パッチ適用とマウントの両方の状態が 100% に達すると、ゲームはデフォルト マップをロードし、Boris、Crunch、および Khaimera が表示されます。パッチ適用やマウントのプロセスで不具合が生じると、何も表示されません。

応用編

この後、チャンク ダウンロード スキームを具体化する手順がいくつかあります。

  • Loading Mode 中に表示され、プログレス バーとプレイヤーへのプロンプトを表示する UI のビルド。

  • タイムアウトやインストールの失敗などのエラーをプロンプトする UI のビルド。

  • アセットに関する追加メタデータを含む PrimaryAssetLabel のカスタム サブクラスの作成。たとえば、Battle Breakers のカスタム PrimaryAssetLabel クラスには、現在のチャンクを使用するための前提条件としてロードされる必要がある親チャンクが含まれています。

Unreal Engine のドキュメントを改善するために協力をお願いします!どのような改善を望んでいるかご意見をお聞かせください。
調査に参加する
閉じる