4.7 UObject custom Serialize problems

I develop a C++ plugin, and I have big trouble with the 4.7 upgrade of one of my custom class.

I expected the UObject::Serialize function to be used for a kind-of custom properties serialization/deserialization, so called each time UE needs to save/load my object. But it seems more subtle, and I need more light on that one.

More details:

  • The concerned class is a simple UObject class, instantiated in an “Instanced” UPROPERTY of a USceneComponent.

  • Even before 4.7, copy-paste and asset migration did not seems to work properly, as if those actions did not use my Serialize function as I expected. ie: As the object is pasted, my Serialize is called to deserialize but the FArchive does not seem to contain the values of the old object (as if the copied instance was never Serialized).

  • After 4.7, I now get a lot of bugs and errors when loading an upgraded 4.6 project:

  • At first launch after upgrade, some deserialized values seems weird, and sometimes the scene got many actors randomly translated as if the scene was corrupted.

  • After saving and re-open, Most of my problematic class instantiated in Blueprint logs “Failed import for …” then “Missing Class … my problematic class instance …”

  • To fix Blueprints “Failed import” I need to manually change a property to mark as unsaved to re-save it.

  • When I hit “Play”, I see my object serializing with the good values, but when unserialized into a “UEDPIE” level, some instances get just zeros in serialized data and in some properties ?!

Anyway, I should have done something wrong, but does anyone could have any clue on what ?

EDIT: more investigation on StaticDuplicate:

As last resort, I’m walking/breakpointing UE code to see what happens, and I found a weird behavior when StaticDuplicate’ing the level for PIE.

As I understand it, StaticDuplicate diffs source object’s fields against their archetypes, then re-apply the diff on duplicated objects.
For “normal” objects, Archetypes are CDOs, BUT for Blueprints the Archetype seems to be an instance of the blueprint, and the diff is re-applied on object that do not seems to be duplicated from this archetype, their are just “recycle” default placeholder instances ! So, only the fields that differs from the archetype (typically relinked UObject* pointers) are duplicated correctly !?

EDIT 2: more investigation on CreateDefaultSubobject:

Looking into CreateDefaultSubobject when ctor’ing the duplicate of my the blueprint, my subobject is CreateDefaultSubobject but do not copy fields from the archetype of the blueprint, it seems because it checks if Outer is non-native (is blueprint), and here, my Outer is an ActorComponent (which is native), here the non-native is the actor at Outer->Outer.

So, it make me wondering if I am even allowed to create subobjects into components ? (which are already sub-objects of actors/BPActors).

I just discover that, my USceneComponent::PostLoad ask for something on my “problmatic class”, but it is not yet loaded (EObjectFlags 0x9). It makes me wonder: When/How make sure that sub-object in properties are fully loaded ?

I submitted a fix for subobject instancing issues in master branch: https://github.com/EpicGames/UnrealEngine/commit/14f9ba1fb1e5464618f010d791e16bdb852f4790

I believe it should fix those issues.

Great Thank you ! I cherry-picked the commit on 4.7.3, and it works great !
Is there any hope to get this patch on 4.7.4 ?
(as I develop a plugin-only thing, if the fix don’t come soon enough, I would have to diry-workarround anyway to plublish my plugin on 4.7)