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"

Save/load package

Hello,

Here is the context : I am currently working on a plugin to make some custom commands (in blueprints) to ease deployment or post builds processes (something that seems a little like the build xml file that make its apparition in UE 4.13).

Well, my issue is that I want to save/load some custom datas. I don't want theses datas to be saved in the Content directory, to hide them from the user and not pollute their project with asset that will not be packaged. So, I want to save these datas in Plugin/MyPlugin/Datas. My datas are stocked in a UObject*.

With that in mind, I thought custom asset was not I wanted since the factory (FactoryNew), perhaps, will force me to make my asset in the Content directory.

Here is the problem : So I am using CreatePackage/SavePackage/LoadPackage. But I am encountering some issues.

For datas creation, I do :

 package = CreatePackage(nullptr, *absoluteFilePath); // Create the package where I want
 ProfileDatas = NewObject<UCCProfileDatas>(package, UCCProfileDatas::StaticClass(), CCProfileDatasSaveDataName); // Create a new object of my datas that will be in the package
 package->MarkPackageDirty(); // Mark package dirty to be able to save it
 
 FStringOutputDevice outputDevice; // Will get error message
 if (UPackage::SavePackage(package, nullptr, EObjectFlags::RF_Public | EObjectFlags::RF_Standalone, *absoluteFilePath, &outputDevice)) // Save the package where I want

Then, to load the datas, I do :

 package = LoadPackage(nullptr, *outPackagePath, LOAD_None);

This works. Until I add some datas in my object. I fill a TArray (as a UPROPERTY). Then I save it, but when I load it again. It crashes here :

LinkerLoad.cpp : line 3586

 UObject* Template = UObject::GetArchetypeFromRequiredInfo(LoadClass, ThisParent, Export.ObjectName, Export.ObjectFlags);
 
 check(Template);

With 'Export.ObjectName = 0x00000017aeada028 "Default_Object"'. I do not know what is this Default_Object.

Any idea ? What I am doing wrong ? Should I use some custom asset to make a correct serialization ?

Product Version: UE 4.10
Tags:
more ▼

asked Oct 03 '16 at 08:47 PM in C++ Programming

avatar image

Begounet
923 32 27 49

avatar image Begounet Oct 04 '16 at 08:30 PM

Well, there is some advancement. Now I can save and load a package like this : ProfileDatas = NewObject(package, UCCProfileDatas::StaticClass(), CCProfileDatasSaveDataName, RF_Public | RF_Standalone);

And after the load package, I can have my object by doing :

 ProfileDatas = FindObject<UCCProfileDatas>(package, *CCProfileDatasSaveDataName.ToString());

It works almost like a charm. Almost. There is an issue when my main object (UCCProfileDatas) contains a UObject* that have been instantiated like this :

 ProfileDatas->Hello = NewObject<UCCDatas>(package, UCCDatas::StaticClass(), TEXT("Hello"));

I tried several things, like settings the ProfileDatas as the Outer, w/ or w/o a name. However, I still get an dependency issue.

It crashes during the SavePackage step.

SavePackage.cpp : line 3860 // If we still didn't find index, maybe it was a duplicate export which got removed. // Check if we have a redirect to original. if (DependencyIndex.IsNull()) { DependencyIndex = ExportToIndexMap.FindRef(DuplicateRedirects[DependentObject]); }

I am not sure what I am suppose to do to not get this dependency issue...

(comments are locked)
10|2000 characters needed characters left

1 answer: sort voted first

Well, the dependency had no link with the real issue... I just misunderstood how the packaging system worked.

For anybody who is in my situation, here is the resolution.

The issue was concerning the paths between package, objects etc. In my situation, I wanted to create a package in a special path (not something like /Game, /Engine etc.). For the example, we will want to create our asset here : "MyProjectPath/Plugins/Datas/CustomAsset.uasset"

To start, we have to register a new mount point. You can do it in the initialization of your module.

 FPackageName::RegisterMountPoint("/MyMountPoint/",  "Absolute/Path/To/MyProjectPath/Plugins")

Or

 FPackageName::RegisterMountPoint("/MyMountPoint/", FPaths::GamePluginsDir())

Now, we create the package with CreatePackage by giving the name with the mount point (not absolute path). Does not require the ".uasset".

 package = CreatePackage(nullptr, TEXT("/MyMountPoint/Datas/CustomAsset"));

Afterwards, you can create the object and set it into the package like this :

 MyDatas = NewObject<UMyDataClass>(package, UMyDataClass::StaticClass(), TEXT("MyObjectName"), RF_Public | RF_Standalone);

NB : If you need to add some UObject* into MyDatas, you just have to do that, giving the package as outer :

 MyDatas->MySubUObject = NewObject<UMyClass>(package, UMyClass::StaticClass(), TEXT("MySubObject"));

Then, to save your package, you need the absolute path + .uasset extension :

 UPackage::SavePackage(package, nullptr, EObjectFlags::RF_Public | EObjectFlags::RF_Standalone, *(TEXT("Absolute/Path/To/File") + FPackageName::GetAssetPackageExtension());

Your object is saved ! Now, the loading. You have to use LoadPackage, using the path with the mount point (the one you used for CreatePackage).

 package = LoadPackage(nullptr, TEXT("/MyMountPoint/Datas/CustomAsset"), LOAD_None);

Once your package is loaded, you have to search your object saved in it. For that, you have to use FindObject (with the name used during the NewObject) :

 MyDatas = FindObject<UMyClass>(package, TEXT("MyObjectName"));

And that's all ! All your datas should be loaded correctly now.

more ▼

answered Oct 05 '16 at 07:45 PM

avatar image

Begounet
923 32 27 49

avatar image zerophase May 30 '17 at 05:46 AM

I tried doing this, but I'm getting a duplicate at the root of Plugin's content directory, as well as, a uasset in the correct location.

avatar image Begounet May 30 '17 at 08:41 AM

I am sorry, I have no idea where in the process it can create a duplicate... If you have Unreal symbols, you might try to dig into the SavePackage function and see if there is something that try to save in your Plugins directory.

avatar image vlad.serbanescu11 Nov 18 '18 at 09:47 PM

Using this method, everything works fine in unpackaged builds. However, in packaged builds, when I call LoadPackage(), I get a lot of "Couldn't find file for [-] requested by async". I can't find any solutions for this.

(comments are locked)
10|2000 characters needed characters left
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