Instanced object property is being nulled in the editor in a child class when its parent Blueprint is recompiled.
[Attachment Removed]
Instanced object property is being nulled in the editor in a child class when its parent Blueprint is recompiled.
[Attachment Removed]
Steps to Reproduce
1. In code, create an InstancedObject class, based on UObject with EditInlineNew, Blueprintable, DefaultToInstanced specifiers.
2. Create a Blueprint actor class, InstanceOwner.
3. Add a property of InstancedObject type to InstanceOwner and set its default value to non-null.
4. Create a InstanceOwner_Child Blueprint class, based on InstanceOwner.
5. Open both InstanceOwner and InstanceOwner_Child for editing.
6. Recompile InstanceOwner.
7. Observe the value of property added in 3. being nulled in InstanceOwner_Child.
[Attachment Removed]
Hello! Regarding this step:
3. Add a property of InstancedObject type to InstanceOwner and set its default value to non-null.Did you mark that as UPROPERTY(Instanced)? If that wasn’t the problem, can you share your source code?
I’m also reminded of this bugfix CL 44220549 / GitHub commit 5025b6d3b4cf7698c026b2d7facd614dc5c2e9f6, but if you’re on UE 5.7 that should be in your engine version already.
[Attachment Removed]
Hello!
The property is created in a Blueprint class, so to have it instanced, I have marked the subobject’s code class as UCLASS(DefaultToInstanced).
#pragma once
#include "CoreMinimal.h"
#include "UObject/Object.h"
#include "InstancedObject.generated.h"
/**
*
*/
UCLASS(EditInlineNew, Blueprintable, DefaultToInstanced)
class INSTANCEDTEST_API UInstancedObject : public UObject
{
GENERATED_BODY()
};
I have attached the sample project with 2 Blueprint actor classes to easily reproduce the issue.
[Attachment Removed]
For a instanced subobject to inherit properly, both the object must be marked as instanced - so the class should be marked UCLASS(DefaultToInstanced), but also the owner’s property must be marked instanced - UPROPERTY(Instanced).
As a consequence, blueprint variables aren’t supported to reference an instanced subobject. If you move that to code, things should work correctly.
[Attachment Removed]
Hello, just checking up on your status. Is moving this property to native acceptable in your scenario? And if you’ve had the chance to try it, does it solve the issue?
[Attachment Removed]
Hello! Apologies for the late reply. I have created a C++ wrapper struct containing a UPROPERTY(Instanced) property and I can confirm that adding this struct to my InstanceOwner Actor has fixed the issue. Thank you for the help!
[Attachment Removed]
Hey there! Sorry for taking long to circle back. I was traveling for work and hadn’t asked someone to check up on my cases.
DefaultToInstanced on the UMyClass does automatically cause UnrealHeaderTool to add some PropertyFlags to UPROPERTIES() of that type and derived types. So:
That has the following purposes:
UPROPERTY(Instanced) the specifier similarly adds CPF_InstancedReference, CPF_ExportObject, EditInline. It adds one more property flag, CPF_PersistentInstance, which specifically makes the instanced subobjects they reference get duplicated from the old CDO to new CDO when objects get reinstanced during compiling. In FFindInstancedReferenceSubobjectHelper::Duplicate() the call to GetInstancedSubObjects only considers subobjects pointed to by properties with CPF_PersistentInstance for retaining across BP CDO reinstancing.
My advice has always been to tag both the class and the property. As for your question, the intended use for DefaultToInstanced, this is my take on it:
My rule of thumb: UPROPERTY(Instance) is for when you want the property to own the subobject, so the reference is what persists its existence across recompilation triggered reinstancing.
Final tally:
I hope that helps!
[Attachment Removed]
Glad to help!
[Attachment Removed]
Hello! While my issue has been solved, I was wondering if you could provide me with more clarity about the DefaultToInstanced flag, to avoid misuse in the future.
The official documentation describes it as:
“All instances of this class are considered “instanced”. Instanced classes (components) are duplicated upon construction. This Specifier is inherited by subclasses.”
I initially interpreted it as marking a class as UCLASS(DefaultToInstanced) would be equivalent to all properties referencing this class having UPROPERTY(Instanced) flag automatically added. If this is not the case, then what is the intended use of DefaultToInstanced?
[Attachment Removed]