Unreal: Dynamic load map from Pak file
目標:在程式運行時加載自定義 Pak 檔案,并打開指定關卡,顯示其中的完整 map 內容
Unreal 的 Pak 檔案內包括了物體,材質,blueprint,map等等,Level 以 map 的形式保存,
Firsr of all, Pak 相關的除錯需要 Package Project 執行,不能在 Editor 里面直接 Launch,否則 FCoreDelegates::MountPak IsBound 為 false , 則無法執行后續操作,
Code
在 GameMode 的 InitGame() 內呼叫如下代碼,
void MyMainClass::MyMainClass::Exe(UWorld *world) {
UE_LOG(LogTemp, Warning, TEXT("Init Main class"));
if (FCoreDelegates::MountPak.IsBound())
{
UE_LOG(LogTemp, Warning, TEXT("LoadPakDelegate(): OnMountPak.IsBound()"));
FString pakPath = TEXT("../../../MyProject3/Content/Paks/MyProject1-MacNoEditor.pak");
IPakFile *pakFile = FCoreDelegates::MountPak.Execute(pakPath, 4);
if (pakFile)
{
const auto& mountPoint = pakFile->PakGetMountPoint();
UE_LOG(LogTemp, Warning, TEXT("LoadPakDelegate(): MountPoint %s"), *mountPoint);
FString pakContentPath = mountPoint + "MyProject1/Content/";
// FPackageName::RegisterMountPoint("/Game/", "../../../MyProject1/Content/");
FPackageName::RegisterMountPoint("/Game/", pakContentPath);
UGameplayStatics::OpenLevel(world, FName(TEXT("Map2")) );
}
}
else
{
UE_LOG(LogTemp, Warning, TEXT("LoadPakDelegate(): OnMountPak.IsBound() Falied"));
}
}
RegisterMountPoint 的分析
static void RegisterMountPoint
(
const FString & RootPath,
const FString & ContentPath
)
This will insert a mount point at the head of the search chain (so it can overlap an existing mount point and win).
引數解釋:
RootPath: Logical Root Path.
ContentPath: Content Path on disk.
Logical Path 是程式運行時會去找的 path 并非實際路徑,根據反復嘗試,只有在這個引數寫成 “/Game/” 的時候才能正確加載到所有資源,若隨意命名可能只能加載到 map 資源,連 map_builtdata 都找不到,會有如下報錯:
LogStreaming: Error: Couldn't find file for package /Game/StarterContent/Maps/Map2_BuiltData requested by async loading code. NameToLoad: /Game/StarterContent/Maps/Map2_BuiltData
我的猜測是當前運行的程式的默認加載路徑是 Game 所以這樣寫可以成功,應該也有方法自定義加載的路徑,但是我暫時不知道,
Content Path 是指需要 mount 到前面這個目錄的內容的父路徑,這個路徑取決于加載的Pak 的當前掛載點和 Pak 內部的檔案路徑,
通過 PakGetMountPoint() 函式得到掛載點為 "../../../"
而且 Pak 內部檔案如下
MyProject1/Content/StarterContent/Blueprints/...
MyProject1/Content/StarterContent/Maps/...
MyProject1/Content/StarterContent/Materials/...
MyProject1/Content/StarterContent/Shapes/...
...
故最終路徑為 “../../../MyProject1/Content/”
Missing shader resource
成功加載 map 但是模型材質和 shader 丟失,log 如下:
[UE4] [2021.05.17-03.57.53:734][ 0]LogShaders: Error: Missing shader resource for hash '589973CAE03D7F0ECFEC6B825B774136FF9FCB9D' for shader platform 16 in the shader library
LogMaterial: Error: Tried to access an uncooked shader map ID in a cooked application
[UE4] [2021.05.17-08.02.25:186][ 0]LogMaterial: Can't compile BasicShapeMaterial with cooked content, will use default material instead
這個問題原因是在要加載 Pak 的工程設定里面啟用了 Share Material Shader Code,啟用這個選項會 “Save shader only once” 這樣的優化選項導致了外部的 shader 無法被找到,
在工程中關閉此開關即可,
Ref:
https://answers.unrealengine.com/questions/363767/how-to-load-a-map-from-a-dynamic-level.html 參見 TestyRabbit May 03 '18 at 4:07 PM 的評論
sample code: https://pastebin.com/ZWAPtynK
https://answers.unrealengine.com/questions/258386/loading-map-from-pak-at-runtime.html top 回答
https://answers.unrealengine.com/questions/963414/view.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/285779.html
標籤:其他
上一篇:fbx查看軟體
下一篇:C#物件屬性淺拷貝和深拷貝
