[UE554]DLCによる追加キャラコンテンツ配布、ボスキャラDLCの作成のチュートリアルをやってみた。

基本的にこれをやった。

コンテンツ配布、DLC | Unreal Engine 5.5 ドキュメンテーション
https://dev.epicgames.com/documentation/ja-jp/unreal-engine/patching-content-delivery-and-dlc-in-unreal-engine

1,ChungDownloader Plugin を設定する

注意
・プロジェクトを作ったら一度ビルドしないと
[ProjectName]/Source/[ProjectName]Build.cs がない状態になります。

2,チャンク用のアセットを準備する

Primary Asset Label の設定はこれが正しいようだ。

フォルダに置けばディレクトリやファイルのパスの設定は不要の様子

パッケージ化したディレクトリに.pak ファイルができあがった。

Audit

 [Tools] > [Asset Audit] の順にクリックして、[Asset Audit] ウィンドウでチャンクを確認することもできます。

3,ChunkDownloader のマニフェストとアセットをホスティングする

ディスク上のサイズ ではなく ファイル サイズ を使用する

マニフェスト ファイルは、次のとおりです。

BuildManifest-Windows.txt

	$NUM_ENTRIES = 9
	$BUILD_ID = PatchingDemoKey
	pakchunk1001-Windows.ucas	400	ver01	1001	/Windows/pakchunk1001-Windows.ucas
	pakchunk1002-Windows.ucas	400	ver01	1002	/Windows/pakchunk1002-Windows.ucas
	pakchunk1003-Windows.ucas	416	ver01	1003	/Windows/pakchunk1003-Windows.ucas
	pakchunk1001-Windows.utoc	383	ver01	1001	/Windows/pakchunk1001-Windows.utoc
	pakchunk1002-Windows.utoc	383	ver01	1002	/Windows/pakchunk1002-Windows.utoc
	pakchunk1003-Windows.utoc	381	ver01	1003	/Windows/pakchunk1003-Windows.utoc
	pakchunk1001-Windows.pak	339	ver01	1001	/Windows/pakchunk1001-Windows.pak
	pakchunk1002-Windows.pak	339	ver01	1002	/Windows/pakchunk1002-Windows.pak
	pakchunk1003-Windows.pak	339 ver01	1003	/Windows/pakchunk1003-Windows.pak
  • バージョン。これは任意の文字列に設定することができます。
  • インデックス。これは、プライマリ ラベル アセットに使用した チャンク インデックス の値と一致する必要があります。
  • ファイルのパス、マニフェスト ファイルが配置される場所との相対パスです。

このファイル作成が面倒なので、pythonで自動化しました。

参考のエラー

log chunkdownloader: error: manifest parse error at ../../../../../../sandbox/ue554assemanager/010chunkdowloader/patchingdemo 4_6 all2/saved/persistentdownloaddir/pakcache/cachedbuildmanifest.txt:1

参考URL

https://forums.unrealengine.com/t/primaryassetlabel-explicitassets/455608

Project/PatchingDemoKeyAuto_python.py


# 1 BuildManifest-Windows.txt to Auto Coding
#  1-1 Open Dir \Windows\PatchingDemo\Content\Paks
import os

dir_path = "./Windows/PatchingDemo/Content/Paks/"

files = os.listdir(dir_path)
#print(files)
txtData=""
#minus global Line -2
filelength=len(files)-2
#txtData=txtData+"	$NUM_ENTRIES = 9"+"\r\n"
txtData=txtData+"$NUM_ENTRIES = "+str(filelength)+"\r"
txtData=txtData+"$BUILD_ID = PatchingDemoKey"+"\r"  
for filename in files:
    globalFindNum=filename.find('global')
    print("globalFindNum= "+str(globalFindNum))
    if(globalFindNum==0):
        pass
    else:
        endNum=filename.find('-')
        filenum=filename[8:endNum]
        fileSize=os.path.getsize(dir_path+filename)
        windowsPath="/Windows/"+filename
        #print("filename= "+filename+" fileSize= "+str(fileSize))
        tab="\t"
        print(tab+filename+tab+str(fileSize)+tab+"ver01"+tab+filenum+tab+windowsPath)
        txtData=txtData+filename+tab+str(fileSize)+tab+"ver001"+tab+filenum+tab+windowsPath+"\r" 
filePath="./BuildManifest-Windows.txt"
f = open(filePath, 'w', encoding='UTF-8')
f.write(txtData)
f.close()

# 2 copy

起動用バッチファイル

@echo off
set cwdirpath=%~dp0
set pythonpath=D:\Sandbox\python\python-3.12.7\
set codepath=%cwdirpath%\
set pyfile=PatchingDemoKeyAuto_python.py

%pythonpath%python.exe %codepath%%pyfile%
::pause
cmd /k

パッケージ ファイルを「/Windows/PatchingDemo/Content/Paks/」から「PatchingDemoKey」フォルダのマニフェストと一緒に並んでいる「Windows」という名前のサブフォルダ内にコピーします。

・ファイルをローカル テスト サーバーでホスティングする

IISサーバーをオンにするためにWindows エクスプローラーで [Start Menu] を開き、[Turn Windows Features on or off (Windows の機能の有効化または無効化)] を検索して開きます

[Windows Features] メニューで、[Internet Information Services (インターネット情報サービス)] を有効にして [OK] をクリックします。

(IIS Managerを開いて [Directory Browsing (ディレクトリをブラウズ)] を有効にします。

[Add MIME Type] ウィンドウで [File Name extension] を .pak に設定し、[MIME type] を「application/octet-stream」に設定します。.ucas と .utoc にも同様の操作をします。

これにより、IIS はリクエストされると、ただファイルをダウンロードします。

[Default Web Site] フォルダに移動します。デフォルトでは「C:\inetpub\wwwroot」です。フォルダを作成し、「PatchingDemoCDN」という名前を付けます。

PatchingDemoKey」フォルダを「PatchingDemoCDN」にコピーします。

プロジェクトのConfig/ DefaultGame.ini ファイルを開き、次の情報を追加して CDN Base URL を定義します。

[/Script/Plugins.ChunkDownloader PatchingDemoLive]
     +CdnBaseUrls=127.0.0.1/PatchingDemoCDN


この URL は、ファイルが配置されているウェブサイトを ChunkDownloader に示しています。PatchingDemoLive 修飾子により、ターゲットのプラットフォームに応じて様々な CDN デプロイ コンフィギュレーションを使用できます。

アセットをパッケージ ファイルに分割し、ローカル ウェブサイトにステージングできたので、Unreal Engine でパッチ適用ソリューションを使用してアクセスすることができるようになりました。

4,ChunkDownloader をゲームに実装する

 PatchingDemoGameInstance を

ブランクなC++プロジェクトにC++フォルダがない状態で、C++ クラスを作る方法
「Tools」プルダウンメニューから「New C++ Class…」を選択します。
ここで新しいクラスを作成できます。

GameInstance

「PatchingDemoGameInstance」を作成

PatchingDemoGameInstance.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Engine/GameInstance.h"
#include "PatchingDemoGameInstance.generated.h"

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FPatchCompleteDelegate, bool, Succeeded);



/**
 * 
 */
UCLASS()
//class UPatchingDemoGameInstance : public UGameInstance
class PATCHINGDEMO_API UPatchingDemoGameInstance :public UGameInstance
{
	GENERATED_BODY()
	public:
        // Overrides
         virtual void Init() override;
         virtual void Shutdown() override;

         UFUNCTION(BlueprintPure, Category = "Patching|Stats")
         void GetLoadingProgress(int32& BytesDownloaded, int32& TotalBytesToDownload, float& DownloadPercent, int32& ChunksMounted, int32& TotalChunksToMount, float& MountPercent) const;	         // Delegates
         
         // Fired when the patching process succeeds or fails
         UPROPERTY(BlueprintAssignable, Category = "Patching");
         FPatchCompleteDelegate OnPatchComplete;

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


 
    protected:
        //Tracks if our local manifest file is up to date with the one hosted on our website
        bool bIsDownloadManifestUpToDate;

        //Called when the chunk download process finishes
        void OnManifestUpdateComplete(bool bSuccess);

        // List of Chunk IDs to try and download
        UPROPERTY(EditDefaultsOnly, Category = "Patching")
        TArray<int32> ChunkDownloadList;

        // 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

// Fill out your copyright notice in the Description page of Project Settings.


#include "PatchingDemoGameInstance.h"

#include "ChunkDownloader.h"
#include "Misc/CoreDelegates.h"
#include "AssetRegistry/AssetRegistryModule.h"



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);
}


void UPatchingDemoGameInstance::Shutdown()
{
    Super::Shutdown();
    // Shut down ChunkDownloader
    FChunkDownloader::Shutdown();
}


void UPatchingDemoGameInstance::OnManifestUpdateComplete(bool bSuccess)
{
    bIsDownloadManifestUpToDate = bSuccess;
}

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;
}

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;
}

void UPatchingDemoGameInstance::OnLoadingModeComplete(bool bSuccess)
{
    OnDownloadComplete(bSuccess);
}

void UPatchingDemoGameInstance::OnMountComplete(bool bSuccess)
{
    OnPatchComplete.Broadcast(bSuccess);
}

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);
    }
}

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

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

新しく GameMode ブループリントを PatchingGameMode という名前で作成します。

Maps」フォルダを作成し、次に 2 つの新規レベルで作成します。

PatchingDemoEntry レベルは空のマップをベースに、
PatchingDemoTest レベルはデフォルトのマップ
ベースにする必要があります。

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

1Game Instance Class (ゲーム インスタンス クラス)CDGameInstance
2Editor Startup Map (エディタのスタートアップ マップ)PatchingDemoTest
3Game Default Map (ゲームのデフォルト マップ)PatchingDemoEntry

CDGameInstance を ブループリント エディタ で開きます。[Details (詳細)] パネルで 3 つのエントリを [Chunk Download List (チャンク ダウンロード リスト)] に追加し、それぞれの値を 100110021003 と入力します。これらがチャンク ID です。

PatchingGameMode を ブループリント エディタ で開き、[EventGraph] に

Bigin Playに

Tickで

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

キャラクター メッシュを表示するには、それらへの参照を取得する必要があります。このセクションでは、アクタのスポーン方法のシンプルな例を説明します。

  1. PatchingDemoTest レベルを開き、次に レベル ブループリント を開きます。
  2. 新規変数を Meshes という名前で作成します。
    • [Variable Type (変数の型)] には [Skeletal Mesh (スケルタルメッシュ)] を選択します。
    • タイプのリストでエントリにマウスオーバーして [Object Reference (オブジェクト参照)] を選択します。

[Meshes (メッシュ)] の [Variable Type (変数の型)] の隣にあるアイコンをクリックし、[Array (配列)] に変更します。ブループリントをコンパイルして変更を適用します。

[Meshes] の [Default Value (デフォルト値)] に 3 つのエントリを追加し、BorisCrunch、およびKhaimera のスケルタルメッシュを選択します。

レベルの イベントグラフ で BeginPlay

レベル内の Player Start を

位置 (256.0, 400.0, 100.0) に移動します。

回転を(0.0,0.0,-90.0)に回転します。

PatchingDemoEntryレベルのゲームモードオーバーライドをPatchingGameModeにします。

Editorでできた!

1,windowsパッケージ化
2,Project/PatchingDemoKeyAuto_cmd.cmd実行

3,Project/BuildManifest-Windows.txt を

4,C:\inetpub\wwwroot\PatchingDemoCDN\PatchingDemoKey へコピー

5,Project\Windows\PatchingDemo\Content\Paks の内容を全部
6,C:\inetpub\wwwroot\PatchingDemoCDN\PatchingDemoKey\Windowsへ コピー

7,Project/WindowsのPatchingDemo.exeを起動

出た!

管理用 全作業データダウンロード

https://drive.google.com/file/d/1YajdJSvuFCg2lAjnPIcIGXcuFC_oHsVm/view?usp=sharing

[UE554] Asset Managerのアセットの非同期ロード機能について試してみた事

https://youtu.be/8LxNPup4TSo

(BP_NextMapPreloadアクターで)非同期ロードはAsync Load Primary Assetノードでやる。(PrimaryAssetを設定するには下の下の設定が必要)

プロジェクト設定で以下の設定をしてUE再起動すると上画像で選べるようになる。Specific Assetでロードマップを設定しないとパッケージでは動かなかった。

その後BP_NextLevelでOpenLevelする。

できたパッケージのテストがこちら

https://youtu.be/8LxNPup4TSo

[UE5.3.2]エラー: UnrealBuildTool.dll が「….\Engine\Binaries\DotNET\UnrealBuildTool\UnrealBuildTool.dll」に見つかりません NuGetパッケージマネージャーは使っちゃダメです!環境壊れます!!!

Windows 11 Pro
UnrealEngine 5.3.2
Visual Studio 2022

今回はぱっとUE5.3.2で作ったC++プロジェクトをzipで別PCに移動したときにおこった。

Using bundled DotNet SDK version: 6.0.302 ERROR: UnrealBuildTool.dll not found in “….\Engine\Binaries\DotNET\UnrealBuildTool\UnrealBuildTool.dll”

ERROR: UnrealBuildTool.dll not found in "..\..\Engine\Binaries\DotNET\UnrealBuildTool\UnrealBuildTool.dll"

発生した問題は、『Generate Visual Studio Project Files』を実行した際に画像のようなダイアログが発生し、『エディタも起動しない』『VisualStudioも起動しない』状態になり、困りました。

C++プロジェクトをビルドするのに必要なチェックが入っていなかった。

動いた

コードのカラーも大丈夫そう

UE5をClean
ProjectをCleanして

Build Solutionしてみた。

========== Build: 11 succeeded, 36 failed, 0 up-to-date, 1 skipped ==========

NuGetが・・・・・・

画像に alt 属性が指定されていません。ファイル名: image-22-1024x668.png

NuGetパッケージマネージャーは安易な気持ちで使っちゃダメです!UE環境壊れます!!!ここから下は参考にするだけにしてください。

AI による概要

詳細

このソリューションに脆弱性のあるNuGetパッケージが含まれているとのことですね。NuGetパッケージの管理には、以下の手順があります。

  1. 1. 脆弱性のあるパッケージの確認:Visual StudioのNuGetパッケージマネージャーまたはパッケージマネージャーコンソールで、脆弱性の可能性があるパッケージを特定します。
  2. 2. パッケージのアップデートまたは削除:削除しちゃだめ!!!!!!!!アップデート
    • アップデート:脆弱性のあるパッケージの最新バージョンが公開されている場合は、それをインストールします。>だめ!!
    • 削除:脆弱性のあるパッケージが不要な場合は、ソリューションから削除します。
  3. 3. ソリューションのビルドとテスト:パッケージの更新または削除後、ソリューションをビルドし、テストして、問題がないことを確認します。

まとめ
• .csprojファイルがなくても問題ありません。
• C++コードの編集・ビルドはそのまま進めてOKです。
• C#ツールのエラーは無視しても大丈夫なことが多いです。
もし「C++コードのビルドや実行で困っていること」があれば、
その具体的なエラーや現象を教えてください。
それに合わせて、さらに詳しくサポートします。

UE53_ThirdPersonCpp.uproject をダブルクリックしたが起動した

HLSLをつかったプロジェクトも大丈夫そうだ。

消し過ぎたので

OpenTracing をUnrealBuildToolをターゲットに再インストールした。

入った

 をUnrealBuildToolをターゲットに再インストールした。
• EpicGames.OIDC や EpicGames.Core などの .NET プロジェクトで、
• OpenTracing
• IdentityModel
• Microsoft.Extensions.*
などの名前空間が見つからないエラーが出ています。

IdentityModelをEpicgames.Core,Epicgames.IODC, UnrealBuildToolをターゲットに再インストールした。

Microsoft.Extensions.ConfigurationをEpicgames.Core,Epicgames.IODC, UnrealBuildToolをターゲットに再インストールした。

Microsoft.Extensions.Options を全ターゲットに再インストールした。

Microsoft.Extensions.DependencyInjection を全ターゲットに再インストールした。

• Microsoft.Extensions.Logging を全ターゲットに再インストールした。

• Microsoft.Extensions.Primitives を全ターゲットに再インストールした。

Solution Clean とSolution Build してみた。だめぽい

  1. .NETプロジェクトのNuGet依存関係エラー
    • OpenTracing.Contrib.NetCore 0.9.0 は Microsoft.Extensions.DependencyInjection.Abstractions (>= 6.0.0 && < 7.0.0) を要求していますが、9.0.5 がインストールされています。
    • そのため、多くの .NET プロジェクトがビルド失敗しています。
    対応策
    • すべての .NET プロジェクトで Microsoft.Extensions.DependencyInjection.Abstractions のバージョンを 6.0.x にダウングレードしてください。

• 他の Microsoft.Extensions.* 系パッケージも 6.0.x に揃えると安全です。

  1. Unreal Engine C++ プロジェクトのビルドエラー
    • System.UnauthorizedAccessException: Access to the path … is denied.
    → ファイルアクセス権限エラーです。
    対応策
    • 該当ファイル(例: SharedDefinitions.Engine.Cpp20.h)や Intermediate/Build ディレクトリに書き込み権限があるか確認してください。
    Visual StudioやEpic Games Launcherを「管理者として実行」してみてください。

• 他のプロセス(例: ウイルス対策ソフトやエクスプローラー)が該当ファイルをロックしていないか確認してください。

まとめ
• .NET系のエラーは「依存パッケージのバージョン不整合」なので、バージョンを6.0.xに揃えることで解消します。

• C++側のエラーは「ファイルアクセス権限」なので、管理者権限やファイルロックの解除で解消します。

Unreal EngineのC++プロジェクト自体は、.NETのNuGet依存エラーがあってもビルドできる場合がありますが、

.NETツールやAutomationToolが必要な場合は、依存エラーを解消しないと正常動作しません。

• OpenTracing.Contrib.NetCore 0.6.2 をEpicgames.Core,Epicgames.IODC, UnrealBuildToolをターゲットに再インストールした。

治らないのでEpic +VS系を全部アンインストールしてインストールすることになりました。

それでNuGet前まで来てやっと治ります。これで正常。

========== Build: 11 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
========== Build completed at 14:42 and took 01:48.725 minutes ==========


自動的に起動した。

やっと回復した。