ChunkDownloader は Unreal Engine (UE) のパッチ適用ソリューションです。これはアセットをリモート サービスからダウンロードし、メモリにマウントしてゲーム内で使用します。これにより、アップデートやアセットを簡単に提供することができます。このガイドでは、プロジェクトに ChunkDownloader を実装する方法を説明します。このガイドを読み終えると、次のことができるようになります。
- Visual Studio を使用して ChunkDownloader を初期化およびシャットダウンする。
- Visual Studio を使用して、ホスト ウェブサイトからパッケージ ファイルをダウンロードする。
- Game Mode ブループリント を設定して、ChunkDownloader を UE に実装する。
- レベル エディタ ビューポート またはゲームでダウンロードしたコンテンツを表示する。
- マウント済みのパッケージ ファイルからコンテンツに安全にアクセスする。
- ローカル マシン上の UE プロジェクトで調整したシステムをテストする。
1.必要な設定と推奨されるアセット
先に進む前に次のガイドを確認し、それぞれの手順に従ってください。
参照ガイドに説明されているように、次の作業が必要になります。
-
空のテンプレート をベースにした C++ プロジェクト を作成します。このプロジェクト名を PatchingDemo と付けます。
-
ChunkDownloader プラグインを [Plugins (プラグイン)] メニューで有効にします。
-
[Use Pak File (pak ファイルを使用)] と [Generate Chunks (チャンクの生成)] を [Project Settings (プロジェクト設定)] > [Project (プロジェクト)] > [Packaging (パッケージ化)] で有効にします。
-
Visual Studio でプロジェクトの
[ProjectName]Build.cs
ファイルを編集します。 -
Visual Studio プロジェクト ファイルを生成します。
-
Visual Studio でプロジェクトをビルドします。
-
Boris、Crunch、および Khaimera の Paragon アセットをこのプロジェクトに追加します。
-
追加したアセットごとに プライマリ アセット ラベル に基づいて データ アセット を調整します。
-
プロジェクトをクックまたはパッケージ化し、パッケージ ファイルをビルド フォルダに含めます。
-
パッケージ ファイルを、ローカルでホスティングされているウェブサイトに配布します。
-
BuildManifest-Windows.txt
という名前のマニフェスト ファイルを作成します。 -
プロジェクトに
DefaultGame.ini
ファイルを定義します。
2.ChunkDownloader を初期化およびシャットダウンする
ChunkDownloader は FPlatformChunkInstall
インターフェースの実装です。これは、ゲームが実行されているプラットフォームによって異なるモジュールを区別なくロードできるさまざまなインターフェースの 1 つです。すべてのモジュールは使用の前にロードして初期化される必要があると同時に、シャットダウンしてクリーンアップされる必要もあります。
ChunkDownloader を使用してこれを行う最も簡単な方法は、カスタムの GameInstance クラスを使用する方法です。GameInstance には関連付けできる適切な初期化とシャットダウン関数が備わっているだけでなく、ゲームの実行中は ChunkDownloader への継続的なアクセスも提供されます。次の手順でこの実装について説明します。
新規 C++ クラス を、ベース クラスとして GameInstance を使用して作成します。名前を PatchingDemoGameInstance にします。
画像をクリックすると拡大されます。
コンパイル プロセスが完了すると、PatchingDemoGameInstance.h
ファイルと PatchingDemoGameInstance.cpp
ファイルが自動的に Visual Studio で開きます。
PatchingDemoGameInstance.h で作業する
ファイルを開くと、PatchingDemoGameInstance.h
内のコードは次のようになります。
PatchingDemoGameInstance.h
#pragma once
#include "CoreMinimal.h"
#include "Engine/GameInstance.h"
#include "PatchingDemoGameInstance.generated.h"
UCLASS()
class UPatchingDemoGameInstance :public UGameInstance
{
GENERATED_BODY()
};
-
文字列
class UPatchingDemoGameInstance :public UGameInstance
を次のように変更します。PatchingDemoGameInstance.h
class PATCHINGDEMO_API UPatchingDemoGameInstance :public UGameInstance
PatchingDemoGameInstance.h
ファイルで宣言する後続のすべての変数、関数、およびプロパティを、UPatchingDemoGameInstance
クラスに追加する必要があります。 -
public
ヘッダの下に、次の関数のオーバーライドを宣言します。PatchingDemoGameInstance.h
public: // Overrides virtual void Init() override; virtual void Shutdown() override;
Init
関数はゲームの起動時に実行されるため、ChunkDownloader を初期化するのに理想的です。同様に、Shutdown
関数はゲームの停止時に実行されるため、ChunkDownloader モジュールをシャットダウンするのに使用できます。 -
protected
ヘッダの下に、次の変数を宣言します。PatchingDemoGameInstance.h
protected: //Tracks if our local manifest file is up to date with the one hosted on our website bool bIsDownloadManifestUpToDate;
-
protected
ヘッダの下に、次の関数を宣言します。PatchingDemoGameInstance.h
protected: //Called when the chunk download process finishes void OnManifestUpdateComplete(bool bSuccess);
PatchingDemoGameInstance.cpp で作業する
-
PatchingDemoGameInstance.cpp
を開きます。ファイルの先頭にある#include "PatchingDemoGameInstance.h"
の下に、次の#includes
を追加します。PatchingDemoGameInstance.cpp
#include "PatchingDemoGameInstance.h" #include "ChunkDownloader.h" #include "Misc/CoreDelegates.h" #include "AssetRegistryModule.h"
これにより ChunkDownloader や、アセットやデリゲートを管理するいくつかの便利なツールにアクセスできるようになります。
-
Init
関数に、次のような実装を作成します。PatchingDemoGameInstance.cpp
void UPatchingDemoGameInstance::Init() { Super::Init(); const FString DeploymentName = "PatchingDemoLive"; const FString ContentBuildId = "PatchingDemoKey"; // initialize the chunk downloader with chosen platform 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 = true; }; Downloader->UpdateBuild(DeploymentName, ContentBuildId, UpdateCompleteCallback); }
このコードの機能をまとめます。
-
関数は
DeploymentName
とContentBuildID
を定義して、DefaultGame.ini
で使用される値と一致させます。今使用しているものはテスト用の固定値ですが、フルビルドでは HTTP リクエストを使用してContentBuildID
をフェッチします。関数は、これらの変数の情報を使用して、ウェブサイトにマニフェストをリクエストします。 -
関数は
FChunkDownloader::GetOrCreate
を呼び出し、ChunkDownloader を設定してその参照を取得すると、それをTSharedRef
にストアします。これは、このプラットフォーム インターフェースまたは同様のプラットフォーム インターフェースへの参照を取得する最も望ましい方法です。 -
関数は目的のプラットフォーム名、この場合は「Windows」を使用して
FChunkDownloader::Initialize
を呼び出します。このサンプルでは、TargetDownloadsInFlight の値は 8 です。この値で、ChunkDownloader が一度に処理するダウンロードの最大数を設定します。 -
関数は
DeploymentName
を使用してFChunkDownloader::LoadCachedBuild
を呼び出します。これは、ディスク上にすでにダウンロードしたファイルがあるかを確認します。それらのファイルが最新のマニフェスト ファイルに更新されている場合は、ChunkDownloader の再ダウンロードをスキップすることができます。 -
関数は
FChunkDownloader::UpdateBuild
を呼び出して、マニフェスト ファイルの更新バージョンをダウンロードします。- システムは、このようにしてまったく新しい実行ファイルを必要とせずに更新パッチをサポートします。
UpdateBuild
はDeploymentName
とContentBuildID
を、操作が成功したか失敗したかを出力するコールバックと一緒に取得します。- また、
OnManifestUpdateComplete
を使用してbIsDownloadManifestUpToDate
を設定することにより、GameInstance でこのフェーズのパッチ適用が終了したことをグローバルに認識することができます。
これらの手順に従うことで ChunkDownloader が初期化され、コンテンツをダウンロードする準備が整っていることを確認し、他の関数にマニフェストの状態を通知します。
-
-
Shutdown
関数に、次のような実装を作成します。PatchingDemoGameInstance.cpp
void UPatchingDemoGameInstance::Shutdown() { Super::Shutdown(); // Shut down ChunkDownloader FChunkDownloader::Shutdown(); }
FChunkDownloader::Shutdown
を呼び出すと、ChunkDownloader が現在処理しているダウンロードがすべて停止し、モジュールをクリーンアップしてアンロードします。 -
OnManifestUpdateComplete
関数に、次のような実装を作成します。PatchingDemoGameInstance.cpp
void UPatchingDemoGameInstance::OnManifestUpdateComplete(bool bSuccess) { bIsDownloadManifestUpToDate = bSuccess; }
この関数は、マニフェストの更新が終了するときに非同期のコールバックとして使用されます。
3.パッケージ ファイルをダウンロードする
ChunkDownloader の適切な初期化およびシャットダウン関数ができたので、このパッケージ ファイルのダウンロード機能を公開することができます。
PatchingDemoGameInstance.h で作業する
-
PatchingDemoGameInstance.h
で、#includes
の下に次のダイナミック マルチキャスト デリゲートを追加します。PatchingDemoGameInstance.h
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FPatchCompleteDelegate, bool, Succeeded);
このデリゲートは Boolean を出力します。これによりパッチのダウンロード操作が成功したかどうかがわかります。デリゲートは通常、ファイルのダウンロードやインストールなどの非同期操作に応答するために使用されます。
-
UPatchingDemoGameInstance
クラスで、public
ヘッダの下にGetLoadingProgress
の次の関数の宣言を追加します。PatchingDemoGameInstance.h
public: UFUNCTION(BlueprintPure, Category = "Patching|Stats") void GetLoadingProgress(int32& BytesDownloaded, int32& TotalBytesToDownload, float& DownloadPercent, int32& ChunksMounted, int32& TotalChunksToMount, float& MountPercent) const;
-
public
ヘッダの下に、次のデリゲート宣言を追加します。PatchingDemoGameInstance.h
public: // Delegates // Fired when the patching process succeeds or fails UPROPERTY(BlueprintAssignable, Category="Patching"); FPatchCompleteDelegate OnPatchComplete;
これにより、パッチ適用操作の完了時にブループリントに接続する場所が用意されます。
-
protected
ヘッダの下に、次のようにChunkDownloadList
の宣言を追加します。PatchingDemoGameInstance.h
protected: // List of Chunk IDs to try and download UPROPERTY(EditDefaultsOnly, Category="Patching") TArray<int32> ChunkDownloadList;
このリストを使用して、後でダウンロードする必要があるチャンク ID をすべて取得します。開発設定では、必要に応じてこれをアセットのリストで初期化します。ただし、テスト目的の場合はこのままデフォルトで公開します。それにより、ブループリント エディタ を使用して入力することができます。
-
public
ヘッダの下に、次のようにPatchGame
の宣言を追加します。PatchingDemoGameInstance.h
public: // Starts the game patching process.Returns false if the patching manifest is not up to date.*/ UFUNCTION(BlueprintCallable, Category = "Patching") bool PatchGame();
この関数により、ブループリントで公開されたパッチ適用処理を開始するための方法が提供され、成功したかしないかを示す Boolean が返されます。これはダウンロード管理やその他の非同期タスクの代表的な手法です。
-
protected
ヘッダの下に、次のように関数宣言を追加します。PatchingDemoGameInstance.h
protected: // 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);
これらを使用して、ダウンロード処理での非同期コールバックに応答します。
PatchingDemoGameInstance.cpp で作業する
-
GetLoadingProgress
関数に、次のような実装を作成します。PatchingDemoGameInstance.cpp
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) * 100.0f; MountPercent = ((float)ChunksMounted / (float)TotalChunksToMount) * 100.0f; }
-
PatchGame
に、次のような実装を作成します。PatchingDemoGameInstance.cpp
bool UPatchingDemoGameInstance::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; } // you couldn't contact the server to validate your Manifest, so you can't patch UE_LOG(LogTemp, Display, TEXT("Manifest Update Failed.Can't patch the game")); return false; }
この関数は次の手順を実行します。
-
最初に、マニフェストが最新かどうかを確認します。ChunkDownloader を初期化していないためにマニフェストの最新版を取得できていない場合、
bIsDownloadManifestUpToDate
が「false」となり、この関数は「false」を返します。これは、パッチ適用の開始に失敗したことを示しています。 -
次に、パッチ適用処理が継続する場合は、関数が ChunkDownloader への参照を取得します。ダウンロード リストを反復処理して、各チャンクの状態を確認します。
- 2 つのコールバックが定義されます。
- 個々のチャンクがダウンロードを完了すると、
DownloadCompleteCallback
が呼び出されます。それぞれのダウンロードが成功または失敗すると、メッセージが出力されます。 LoadingModeCompleteCallback
は、すべてのチャンクがダウンロードされると実行されます。
- 個々のチャンクがダウンロードを完了すると、
-
関数は
FChunkDownloader::DownloadChunks
を呼び出して、ChunkDownloadList
にリスト表示されている必要なチャンクのダウンロードを開始します。この関数を呼び出す前に、このリストに必要なチャンク ID が入力されている必要があります。また、DownloadCompleteCallback
も渡されます。 - 関数は、先ほど定義したコールバックを使用して
FChunkDownloader::BeginLoadingMode
を呼び出します。- Loading Mode にすると、ChunkDownloader はダウンロード状態の監視を開始します。
- チャンクは Loading Mode を呼び出さずにバックグラウンドで受動的にダウンロードできますが、使用することでダウンロード Stats が出力され、ユーザーがダウンロードの進捗をトラッキングできる UI を作成することができます。
- チャンクのバッチ全体がダウンロードされるときに、コールバック関数を使用して特定の機能を実行することもできます。
-
-
次のように
OnDownloadComplete
とOnLoadingModeBegin
関数の実装を作成します。PatchingDemoGameInstance.cpp
void UPatchingDemoGameInstance::OnLoadingModeComplete(bool bSuccess) { OnDownloadComplete(bSuccess); } void UPatchingDemoGameInstance::OnMountComplete(bool bSuccess) { OnPatchComplete.Broadcast(bSuccess); }
OnLoadingModeComplete
はOnDownloadComplete
に渡され、後の手順でチャンクのマウントに進みます。OnMountComplete
はすべてのチャンクがマウントを完了し、コンテンツを使用する準備が整っていることを示します。 -
OnDownloadComplete
関数に、次のような実装を作成します。PatchingDemoGameInstance.cpp
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); } }
これも複雑な関数のため、これから細かく説明します。これは、ユーザーのデバイスにパッケージ ファイルのダウンロードが成功すると実行されます。
-
ChunkDownloader への参照を取得します。
-
関数は Json 配列を設定し、
ChunkDownloadList
の情報を入力します。これは、リクエストの作成に使用されます。 -
関数は
MountCompleteCallback
を使用して、パッチが正常に適用されたかどうかを出力します。 -
関数は Json リストと
MountCompleteCallback
を使用してChunkDownloader::MountChunks
を呼び出し、ダウンロードされたチャンクのマウントを開始します。 -
ダウンロードに成功すると、関数は
OnPatchComplete
デリゲートを値 true でアクティベートします。ダウンロードに失敗すると、値false
でアクティベートします。UE_LOG
は失敗の場所に応じてエラー メッセージを出力します。
-
4.パッチ適用のゲーム モードを設定する
パッチ適用プロセスを開始するために、レベル と、PatchGame
を呼び出して画面にパッチ適用 Stats を出力するための ゲーム モード を作成することができます。
-
Unreal Editor で、新規「Blueprints」フォルダを コンテンツ ブラウザ に作成します。次に、ベース クラスとして PatchingDemoGameInstance を使用して 新しいブループリント を作成します。
新しいブループリント クラスの名前を「CDGameInstance」にします。
このブループリントを使用することで、設定の編集とチャンクのダウンロード プロセスのトラッキングによりアクセスしやすくなります。
-
新しく ゲーム モード ブループリントを PatchingGameMode という名前で作成します。
-
「Maps」フォルダを作成し、次に 2 つの新規レベルを PatchingDemoEntry と PatchingDemoTest という名前で作成します。PatchingDemoEntry レベルは空のマップをベースに、PatchingDemoTest レベルはデフォルトのマップをベースにする必要があります。
-
[Project Settings (プロジェクト設定)] を開いて [Project] > [Maps & Modes (マップ & モード)] に移動します。次のパラメータを設定します。
画像をクリックすると拡大されます。
ID パラメータ 値 1 Game Instance Class (ゲーム インスタンス クラス) CDGameInstance 2 Editor Startup Map (エディタのスタートアップ マップ) PatchingDemoTest 3 Game Default Map (ゲームのデフォルト マップ) PatchingDemoEntry -
CDGameInstance を ブループリント エディタ で開きます。[Details (詳細)] パネルで 3 つのエントリを [Chunk Download List (チャンク ダウンロード リスト)] に追加し、それぞれの値を 1001、1002、1003 と入力します。これらがチャンク ID です。
パッチ適用のゲーム モードで作業する
-
PatchingGameMode を ブループリント エディタ で開き、[EventGraph] に移動します。
-
Get Game Instance ノードを作成し、次にそれを CDGameInstance にキャストします。
-
As CDGameInstance ピンをドラッグし、次に Promote to Variable をクリックしてゲーム インスタンスへの参照を作成します。新規変数の Current Game Instance を呼び出します。
-
Set Current Game Instance の出力ピンをクリックしてドラッグし、Patch Game への呼び出しを作成します。
-
Patch Game の Return Value をドラッグし、次に Promote to Variable をクリックして値をストアする Boolean を作成します。新規変数の Is Patching In Progress を呼び出します。
画像をクリックすると拡大されます。
-
Try Patch Count という名前の整数変数を作成して、Get Try Patch Count ノードを Graph にドラッグします。
-
Get Try Patch Count ノードの出力ピンをドラッグして、Increament Int ノードを作成します。
-
Is Patching In Progress の出力ピンをドラッグして、Branch ノードを作成し、その False ピンを Increament Int ノードに接続します。
-
Increament Int ノードの出力ピンをドラッグして別の Branch ノードを作成し、その False ピンをドラッグして Delay ノードを作成します。
-
Delay ノードの Complited ピンを Patch Game ノードの入力ピンで接続します。
-
Greater ノードを作成します。その A Input ピンを Increament Int ノードの Result ピンに接続します。その Return 入力を 2 番目の Branch ノードの Condition ピンに接続します。
画像をクリックすると拡大されます。
-
Tick イベントをドラッグし、新しい Branch ノードを作成します。Is Patching In Progress をその Condition 入力にアタッチします。
-
Branch ノードの True ピンをドラッグして、次に Print String ノードを作成します。これを使用して、ダウンロード割合を表示します。Print String ノードを使用して、マウント割合を表示します。
-
Get Current Game Instance ノードを作成し、次にその出力ピンをドラッグし、Get Patch Status への呼び出しを作成します。
-
Get Loading Progress ノードの Download Percent ピンからドラッグして Build String (float) ノードを作成します。
-
Prefix ピンのテキスト フィールドに Current Loading Progress を入力し、Suffix ピンのテキスト フィールドに % を入力します。
-
Get Loading Progress ノードの Mount Percent ピンからドラッグして Build String (float) ノードを作成します。
-
Prefix ピンのテキスト フィールドに Current Mount Progress を入力し、Suffix ピンのテキスト フィールドに % を入力します。
-
最初の Print String ノードのロードの進捗のために、Build String (Float) の Return Value を接続します。
-
2 番目の Print String ノードのマウントの進捗のために、Build String (Float) の Return Value を接続します。
-
Print String ノードから Branch ノードを作成し、次に AND ノードを作成して Condition ピンに接続します。
-
Greater Equal ノードを作成して Download Percent が 100.0 以上かどうかを確認し、次に同じ設定を Mount Percent にも行います。それら両方を AND ノードに接続します。どちらの条件も true の場合、Open Level を使用して PatchingGameTest レベルを開きます。
画像をクリックすると拡大されます。
これで、ゲームを実行するとエントリ マップが開き、ChunkDownloader が実行され、チャンク ダウンロード リストに載っているチャンクのダウンロードおよびマウンティングの進捗が出力されます。ダウンロードが完了すると、テスト マップに遷移します。
Play In Editor を使用してこれを実行しようとすると、ダウンロードが開始されません。ChunkDownloader はパッケージ化されたビルドでテストする必要があります。
5.ダウンロードしたコンテンツを表示する
キャラクター メッシュを表示するには、それらへの参照を取得する必要があります。このセクションでは、アクタのスポーン方法のシンプルな例を説明します。
-
PatchingDemoTest レベルを開き、次に レベル ブループリント を開きます。
- 新規変数を Meshes という名前で作成します。
- [Variable Type (変数の型)] には [Skeletal Mesh (スケルタルメッシュ)] を選択します。
- タイプのリストでエントリにマウスオーバーして [Object Reference (オブジェクト参照)] を選択します。
-
[Meshes (メッシュ)] の [Variable Type (変数の型)] の隣にあるアイコンをクリックし、[Array (配列)] に変更します。ブループリントをコンパイルして変更を適用します。
-
[Meshes] の [Default Value (デフォルト値)] に 3 つのエントリを追加し、Boris、Crunch、およびKhaimera のスケルタルメッシュを選択します。
-
レベルの イベントグラフ で BeginPlay イベントからドラッグし、For Each Loop を作成して Meshes の配列に接続します。
-
For Each Loop の Array Element ピンをドラッグして、Is Valid ノードを作成します。
-
Spawn Actor From Class ノードを作成して Is Valid ノードの Is Valid ピンに接続します。Class に Skeletal Mesh Actor を選択します。
-
For Each Loop の Array Index をドラッグして、Multiply ノードを作成します。浮動小数値を 256 に設定します。
- もう 1つ Multiply ノードを作成します。前の Multiply ノードの Return value ピンを、作成した Multiply ノード の B Input Value ピンに接続します。B Input Value ピンを右クリックして [Convert to (接続先)] > [Vector (ベクター)] を選択することで、この Multiply ノードの B Input Value ピンを Vector に接続します。ベクターの値を (1.0, 0.0, 0.0) と入力します。
- これにより、For Each loop を通過するたびに、座標が原点から 256 単位離れます。これにより、スポーン時にメッシュごとにいくらかの空間が与えられます。
-
前述の手順のベクターを Make Transform ノードの Location として使用し、次に Return Value を Spawn Actor ノードの Spawn Transform 入力に接続します。
-
Spawn Actor ノードの Return Value をドラッグして、スケルタルメッシュ コンポーネント への参照を取得します。それを使用して Set Skeletal Mesh を呼び出します。
-
For Each Loop ノードの Array Element ピンをドラッグして、このノードの出力を Set Skeletal Mesh の New Mesh 入力ピンに接続します。
画像をクリックすると拡大されます。
-
レベル内の Player Start を (256.0, 800.0, 100.0) に移動します。
画像をクリックすると拡大されます。
- 作業を保存してブループリントをコンパイルします。
レベルをロードすると、キャラクターごとのスケルタルメッシュがスポーンします。オブジェクト リファレンスが機能しない場合、各キャラクターのチャンクがマウントされていないため、アセットを使用することができず、スポーンしません。

6.ゲームをテストする
最後に、プロジェクトをスタンドアローン ビルドでテストする必要があります。Pak のマウンティングは PIE モードでは機能しません。そのため、これはパッチ適用機能をテストするための必要な手順です。
-
プロジェクトをパッケージ化します。
-
パッケージ ファイルとマニフェストを IIS テスト ウェブサイト の対応するフォルダにコピーします。
-
IIS プロセスとウェブサイトの両方が実行中であることを確認します。
-
パッケージ化された実行ファイルを実行します。
最終結果
画面の左上にパッチ適用出力が表示されている黒い画面を確認することができます。次に、パッチ適用とマウントの両方の状態が 100% に達すると、ゲームはデフォルト マップをロードし、Boris、Crunch、および Khaimera が表示されます。パッチ適用やマウントのプロセスで不具合が生じると、何も表示されません。
応用編
この後、チャンク ダウンロード スキームを具体化する手順がいくつかあります。
-
Loading Mode 中に表示され、プログレス バーとプレイヤーへのプロンプトを表示する UI のビルド。
-
タイムアウトやインストールの失敗などのエラーをプロンプトする UI のビルド。
-
アセットに関する追加メタデータを含む PrimaryAssetLabel のカスタム サブクラスの作成。たとえば、Battle Breakers のカスタム PrimaryAssetLabel クラスには、現在のチャンクを使用するための前提条件としてロードされる必要がある親チャンクが含まれています。