C++ derived UDataAsset lost after crash

Hello,

I found a bug with causes the loss of an asset.

1.) Create a C++ class deriving from UDataAsset
2.) Create an DataAsset of the new class
3.) Edit the values of the DataAsset , save and keep the editing window open
4.) Edit the C++ class definition and recompile
5.) The engine crashes and the data asset will not be reloaded when you reopen the project next time

Usually UE discovers.uasset files but this one does not appear in the content browser anymore although it is still in the folder.

Hey EddyTheTank-

Could you elaborate on your reproduction steps with more detail? I’ve created a class based on DataAsset and created a new DataAsset in the editor based on my class. What exactly do you mean by Edit the values of the data asset? Did you add anything to the DataAsset class and if so what was added?

Cheers

Hello

You sould have a UCustomDataAsset : public UDataAsset

3.1 Double click the new asset in the content browser
3.2 Modifiy some of its properties in the new DataAsset window
3.3 Save the DataAsset but keep the window open

  1. Now when you edit the UCustomDataAsset and change the type of an existing UPROPERTY it seems to crash the editor, however the original serialized version of the asset is still in the folder. But when you reload the editor it can’t deserialize the asset anymore, because the types have changed.(I assume)

Since it is only serializing UPROPERTY members, there should be information about type and variable name available during serialization. Wouldn’t it be better to implement some sort of a type and name check?

If ( type mismatch or name mismatch) set default value
else deserialize

In my case I have implemented a VehicleDefinition DataAsset that stores a lot of data for vehicle setups. There will probably be around 100-200 assets of this type later on, it would be a pain to loose this data everytime you change the type of a variable. Maybe it would be a good idea to implement some sort of UJSONDataAsset ?

After creating the new class I returned to the editor and, in the content browser, clicked Add New->Miscellaneous->Data Asset. In the “Pick Data Asset Class” window I select CustomDataAsset. This is what the NewDataAsset window looks like when I open it.

Without adding any code to the class it leaves the data asset empty. Can you explain what you’re doing when you say “Modify some of its properties”?

Hi EddyTheTank,

We have not heard back from you in a few days, so we are marking this post as Resolved for tracking purposes. If you are still experiencing the issue you reported, please respond to this message with additional information and we will offer further assistance.

Thank you.

Hi,

I create a new C++ class UCustomDataAsset for example, inside this class I add properties

UPROPERTY(EditAnywhere, Category = SomeCategory)
	float someProperty1;

UPROPERTY(EditAnywhere, Category = SomeCategory)
	float someProperty2;

Now I create a asset of UCustomDataAsset and fill in some values for someProperty1 and someProperty2 and save the project.

When you edit the C++ class now and insert another property “someProperty3” it will look like this:

UPROPERTY(EditAnywhere, Category = SomeCategory)
	float someProperty1;


UPROPERTY(EditAnywhere, Category = SomeCategory)
	float someProperty3;

UPROPERTY(EditAnywhere, Category = SomeCategory)
	float someProperty2;

after recompilation it may happen that previously saved assets lose their data because they can’t be deserialized anymore and when I have an old asset opened during recompilation the editor may even crash because the old asset can not be loaded.

When you reopen the project without saving the project after recompilation of the modified C++ class, it won’t be able to load the old data asset anymore. If you try to load asset with FObjectFinder you get error messages that the asset can not be found.

Since UnrealEngine generates reflection data using UCLASS USTRUCT UPROPERTY, why can’t you generate a autoserialization algorithm that takes into account the variable name during serialization/deserialization? Check whether the variable exists and fill it with default constructor values if it doesn’t.

Imagine you have a project with a few hundred data assets and need to modify the c++ class, all your data will be lost.

Best regards

Hey EddyTheTank,

I followed the steps you provided and noticed that after a hot reload, if the data asset was open in the editor then the property values for the open asset are not editable. However closing and reopening the asset converted the variables back to their original values along with allowing the new property value to be changed.

I did notice a crash when closing the project if the editor asset was not saved after a hot reload (UE-27978) but saving the data asset after the hot reload did not cause any crash.

Cheers