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 aUSceneComponent
. -
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 theFArchive
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).