x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

How to load assets from a pak file at runtime?

Now I have a pak file, which contains some .uasset files. I want to load the .uasset files at runtime but the code doesn't work right. The code is as below:

     IPlatformFile &PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
     FPakPlatformFile *PakPlatfromFile = new FPakPlatformFile;
     PakPlatfromFile->Initialize(&PlatformFile, TEXT(""));
     FPakFile PakFile(PakFileName, false);
     UE_LOG(LogDynamicStaticMeshActor, Log, TEXT("Init - IsPakFileValid:%d"), PakFile.IsValid());
     FString MountPoint(FPaths::EngineDir());
     int32 PakOrder = 0;
     if (!PakPlatfromFile->Mount(PakFileName, PakOrder, *MountPoint)) {
         UE_LOG(LogDynamicStaticMeshActor, Fatal, TEXT("Mount error"));
     }
 
     UObjectLibrary *ObjectLibrary = ConstructObject<UObjectLibrary>(UObjectLibrary::StaticClass());
     ObjectLibrary->UseWeakReferences(true);
     ObjectLibrary->AddToRoot();
     UE_LOG(LogDynamicStaticMeshActor, Log, TEXT("Before load asset"));
     ObjectLibrary->LoadAssetDataFromPath(MountPoint);
     if (ObjectLibrary->IsLibraryFullyLoaded()) {
         UE_LOG(LogDynamicStaticMeshActor, Log, TEXT("Fully loaded"));
         ObjectLibrary->LoadAssetsFromAssetData();
     }
 
     TArray<FAssetData> AssetDataList;
     int32 count = ObjectLibrary->GetAssetDataCount();
     UE_LOG(LogDynamicStaticMeshActor, Log, TEXT("count:%d"), count);

It seems the mount step is successful, but when it runs to ObjectLibrary->LoadAssetDataFromPath(MountPoint), it is not fully loaded belong to the log, and ObjectLibrary->GetAssetDataCount() returns zero.

Also I've tried other ways:

 void ADynamicStaticMeshActor::Init(const TCHAR* PakFileName) {
     IPlatformFile &PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
     FPakPlatformFile PakPlatfromFile;
     PakPlatfromFile.Initialize(&PlatformFile, TEXT(""));
     FPakFile PakFile(PakFileName, false);
     UE_LOG(LogDynamicStaticMeshActor, Log, TEXT("Init - IsPakFileValid:%d"), PakFile.IsValid());
     FString MountPoint(TEXT("/Engine/Content/DLC/"));
     int32 PakOrder = 0;
     if (!PakPlatfromFile.Mount(PakFileName, PakOrder, *MountPoint)) {
         UE_LOG(LogDynamicStaticMeshActor, Fatal, TEXT("Mount error"));
     }
 
     TArray<FString> AssetFileNames;
     PakFile.FindFilesAtPath(AssetFileNames, *MountPoint);
 
     for (const FString &AssetName : AssetFileNames) {
         UE_LOG(LogDynamicStaticMeshActor, Log, TEXT("AssetName:%s"), *AssetName);
     }
 
     FString MaterialFilePath = MountPoint + TEXT("BR_DongChenMingHan_6.uasset");
     FString MaterialFileContent;
     FFileHelper::LoadFileToString(MaterialFileContent, *MaterialFilePath);
     UE_LOG(LogDynamicStaticMeshActor, Log, TEXT("Path:%s Content:%s"), *MaterialFilePath, *MaterialFileContent);
 
     UStaticMeshComponent *StaticMeshComponent = NewObject<UStaticMeshComponent>(this, TEXT("staticMeshCom"));
     FStreamableManager StreamableManager;
     FString AssetName(MaterialFilePath);
     FStringAssetReference AssetRef(AssetName);
     Cast<UMaterial>(StaticLoadObject(UMaterial::StaticClass(), nullptr, *AssetName));
     UObject *Object = StreamableManager.SynchronousLoad(AssetRef);
     UMaterial *Material = Cast<UMaterial>(Object);
 }
 

it could not load the assset file BR_DongChenMingHan_6.uasset to string. So I'm not sure whether the mount step is successful? And when loading the asset using StaticLoadObject, It logs "can't find object" and I am really confused about this log for the file path seems correct. The related log is as below:

 LogDynamicStaticMeshActor: Init - IsPakFileValid:1
 LogDynamicStaticMeshActor: Path:/Engine/Content/DLC/BR_DongChenMingHan_6.uasset Content:
 LogLinker:Warning: Can't find file '/Engine/Content/DLC/BR_DongChenMingHan_6'
 LogLinker:Warning: Can't find file '/Engine/Content/DLC/BR_DongChenMingHan_6'
 LogUObjectGlobals:Warning: Failed to find object 'Material /Engine/Content/DLC/BR_DongChenMingHan_6.uasset'
 LogDynamicStaticMeshActor: Before load Object
 LogLinker:Warning: Can't find file '/Engine/Content/DLC/BR_DongChenMingHan_6'
 LogUObjectGlobals:Warning: Failed to find object 'Object /Engine/Content/DLC/BR_DongChenMingHan_6.uasset'
 LogStreamableManager: Failed attempt to load /Engine/Content/DLC/BR_DongChenMingHan_6.uasset

It's very kind of u if anyone teach me the right resolution, for I've spent several days on this problem.

Product Version: UE 4.9
Tags:
more ▼

asked Dec 17 '15 at 12:00 PM in C++ Programming

avatar image

daoce
11 1 2 2

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

7 answers: sort voted first

Hi~

I have just solved this problem.

The key is the asset's path.

Remeber,When you are using the StaticLoadObject method.

You path should be Path1/Path2/Pathxx/AssetName.AssetName

Instead of AssetName.uasset or AssetName.umap...

try to change the path and let me know if you solve this problem

Here is my code,and it worked correctly!!

alt text

1.png (86.7 kB)
more ▼

answered Sep 30 '16 at 07:07 AM

avatar image

DennisDing
55 3 9 11

avatar image Rumbleball Feb 28 '18 at 04:23 PM

Copy&Paste

     void AAssetLoad::LoadPakFile()
     {
         IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
         FPakPlatformFile* PakPlatformFile = new FPakPlatformFile(); 
         PakPlatformFile->Initialize(&PlatformFile, TEXT(""));
         FPlatformFileManager::Get().SetPlatformFile(*PakPlatformFile);
 
         const FString PakFilename = FPaths::GameContentDir() + TEXT("Data/OutPak1.pak");
         FPakFile PakFile(*PakFilename, false);
         
         const FString MountPoint(FPaths::EngineContentDir());
         PakFile.SetMountPoint(*MountPoint);
 
         if (PakPlatformFile->Mount(*PakFilename, 0, *MountPoint))
         {
             UE_LOG(LogClass, Log, TEXT("Mount Success"));
             TArray<FString> FileList;
 
             PakFile.FindFilesAtPath(FileList, *PakFile.GetMountPoint(), true, false, true);
             FStreamableManager StreamableManager;
             
             // Static load object
             FString AssetName = FileList[0];
             FString AssetShortName = FPackageName::GetShortName(AssetName);
             FString LeftStr;
             FString RightStr;
             AssetShortName.Split(TEXT("."), &LeftStr, &RightStr);
             AssetName = TEXT("/Engine/") + LeftStr + TEXT(".") + LeftStr;
             FStringAssetReference Reference = AssetName;
 
             UObject* LoadObject = StreamableManager.SynchronousLoad(Reference);
             if (LoadObject != nullptr)
             {
                 UE_LOG(LogClass, Log, TEXT("Object load Success..."));
             }
             else
             {
                 UE_LOG(LogClass, Error, TEXT("Can't load asset..."));
             }
         }
         else
         {
             UE_LOG(LogClass, Error, TEXT("Mount failed"));
         }
     }
avatar image UnrealLF Jun 08 '18 at 07:33 AM

Print "Can't load asset..."

avatar image Rumbleball Jun 08 '18 at 01:13 PM

Its been some month since I did that stuff. If I remember right this code did not work for me directly either. You also must make sure you mountpoint and stuff is correct. He sets the mountpoint manually. Try to omit that. The mountpoint is in the pakfile and should get read automatically. Try debug the code and see where it goes wrong.

Another thing: This is very basic code just to get you started. The code creates a new FPakPlatformfFile every time. That is bullshit. You only need one. I made a singleton class that creates that file uppon creation and caches it.

I wanted to provide the Plugin I made via Marketplace, but as I'm again working on other stuff I haven't got to test it toroughly.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

I don't understand why you use LoadFileToString. Why do you want to load a uasset into a string ? Maybe this is because I don't use FStreamableManager but I would build this way :

 FString MaterialFilePath = MountPoint + TEXT("BR_DongChenMingHan_6.BR_DongChenMingHan_6"); // the reference to the object in the engine, not the path of the file
 UMaterial *Material = Cast<UMaterial>(StaticLoadObject(UMaterial::StaticClass(), NULL, *MaterialFilePath));

Also I don't understand why this line don't return any log :

 UE_LOG(LogDynamicStaticMeshActor, Log, TEXT("AssetName:%s"), *AssetName);

Are you sure that you have uasset files into your pak file ?

more ▼

answered Dec 17 '15 at 01:29 PM

avatar image

Schopi
41 4 7 11

avatar image daoce Dec 18 '15 at 02:37 AM

I mistakenly thought the mount is just like the shell command mount, which maps the files under a path. But I still don't understand what "the reference to the object in the engine" exactly means, would u mind give me some documents? After all, it still logs can't find file '/Engine/Content/DLC/BR_DongChenMingHan_6' even though I change the path to MountPoint + TEXT("BR_DongChenMingHan_6.BR_DongChenMingHan_6")

that UE_LOG(LogDynamicStaticMeshActor, Log, TEXT("AssetName:%s"), *AssetName) doesn't log may be because that PakFile.setMountPoint is not called. And I am quite sure the pak file contains BR_DongChenMingHan_6.uasset for I've extracted it to a folder using UnrealPak.exe

avatar image Schopi Dec 18 '15 at 10:00 AM

The reference to the object is what you get in the editor when you right click on an asset and pick "copy reference". You can see that even if this is a path, the extension is not '.uasset'. It looks like '/Game/Content/DLC/BR_DongChenMingHan_6.BR_DongChenMingHan_6' and Game/ is replaced by /Engine when the asset is mounted. So yes the mount kind of maps the files under a path but not exactly I guess.

Anyway you already have a problem before if the *AssetName is not logged during your loop. I don't see any difference between your code and mine so if you are absolutely sure that you have your asset into your pak file I don't know what your problem is.

avatar image daoce Dec 24 '15 at 10:00 AM

Thank you for your reply and now I can load assets under the game folder at runtime, but still cannot load assets from a pak file. I'm absolutely sure that the pak file contains the assets. Or would u mind show me the right code, for I've spent tens of hours on this problem but still have no answer.

avatar image Schopi Jan 04 '16 at 11:47 AM

No, sorry, I can't. I don't have the legal right to do this.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

这个问题,我也在研究,好像PAK文件mount后,必须要注册,见引擎源文件的UObjectBase::AddObject接口,加我的QQ:1346362278

more ▼

answered Jan 03 '16 at 11:25 AM

avatar image

mikeche6362
0 2 4 5

avatar image dongquan360 May 05 '16 at 02:02 AM

我是在异步加载资源的时候遇到问题,FStreamableManager 的RequestAsyncLoad方法,日志输出LogLinker:Warning: The file '../../../LoadTest/Content/Content/ArchVis/Textures/T_Wood_S.uasset' contains unrecognizable data, check that it is of the expected type. 是不是我pak文件生成有问题,你的pak文件是怎么生成的,我用的ProjectLauncher来做的基于一个release的dlc

avatar image BigBen1992 Jul 15 '17 at 12:27 PM

我也是这个问题!!!!!!

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

When I put the .pak file on default folder "./Content\Paks" and application init for the first time it load the asset and I can use it. But if I drag and drop another .pak file to the same folder during runtime, the application don't load the content to memory. Even if I code an explicit method to do it.

It's possible to replicate the behaviour of loading a *.pak file content at init() method during runtime ?

Regards, Nelson

more ▼

answered Mar 02 '16 at 07:56 PM

avatar image

NelsonBilber
6 1 2

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

我现在也在做从pak文件中加载*.uasset,可以mount到指定的目录,但是最后加载*.uasset失败,大家能给点建议吗?

more ▼

answered Jul 17 '16 at 12:41 PM

avatar image

helloliu
1 1 4

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

alt text

more ▼

answered Jul 20 '16 at 03:32 AM

avatar image

helloliu
1 1 4

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
more ▼

answered Feb 20 '17 at 01:55 PM

avatar image

panha
23 6 13 10

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question