Instanced Object Property of ActorComponent initializes without edited values in inspector

It seems that an instanced UObject as an ActorComponent property doesn’t care about its edited values on the BP. That same UObject as an instanced property of the Actor itself (which contains the ActorComponent) does work.

So in the BP, if I edit SomeNumber to the instanced object:

On BeginPlay() Only for the ActorComponent it will be 0. For the Actor it will be 999.

Any ideas why?

Classes:

UCLASS(DefaultToInstanced)
class UTestObject : public UObject
{
	GENERATED_BODY()

protected:

	UPROPERTY(EditDefaultsOnly)
	int32 SomeNumber;
};

UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
class UTestActorComponent : public UActorComponent
{
	GENERATED_BODY()

	UTestActorComponent()
	{
		TestObject = CreateDefaultSubobject<UTestObject>("TestObject");
	}
	
protected:
	UPROPERTY(EditDefaultsOnly, Instanced)
	TObjectPtr<class UTestObject> TestObject;
};

UCLASS()
class ATestActor : public AActor
{
	GENERATED_BODY()

public:
	ATestActor()
	{
		TestActorComponent = CreateDefaultSubobject<UTestActorComponent>("TestActorComponent");
		TestObject = CreateDefaultSubobject<UTestObject>("TestObject");
	}

protected:
	UPROPERTY(EditDefaultsOnly)
	TObjectPtr<class UTestActorComponent> TestActorComponent;

	UPROPERTY(EditDefaultsOnly)
	TObjectPtr<class UTestObject> TestObject;
};

I believe that’s because you’re creating a new object on the constructor, thus overriding the instance that was created in the editor from the drop down. Try commenting out the CreateDefaultSubobject inside the Component constructor. I’ve used Instanced objects in Components before and it works fine. I just never create them in code. You just have to check if it’s valid before doing anything on it because you might have left the drop down empty.

I second @zeaf, remove it from the constructor. Don’t directly set them to anything as it’s going to use the CDO from C++ and override whatever the blueprint’s do. To confirm that you could Change the value of somenumber in your c++ constructor to a known number and see if that becomes the default value.

Generally I’m always using Instanced with DefaultToInstanced also.

Thanks guys! @zeaf & @Rumzie that was it. You’ll also need to put the “EditInlineNew” specifier on the UCLASS from the Object. It was confusing that for the Actor worked, even with the same constructor initialization than the ActorComponent, but didn’t behave the same. It may be that the ActorComponent was reset, being part of the Actor, and the Actor wasn’t.

Thanks again!

Glad it worked. I also seem to find myself using a collection of keywords for editor object’s that need to be editable and instanced. Seems like you found your correct combo.

1 Like