AActor Instance Component Add Inconsistency

Hello!

So, we’ve been doing some work that requires looking at the InstanceComponents array on an AActor. We noticed some possible inconsistency between the InstanceComponents array and the OwnedComponents set in the AActor class. This was discovered in 5.3, but the code in 5.5 appears unchanged.

There are two ways to add to the InstanceComponents array

void AActor::AddInstanceComponent(UActorComponent* Component) { Component->CreationMethod = EComponentCreationMethod::Instance; InstanceComponents.AddUnique(Component); }and

`void AActor::AddOwnedComponent(UActorComponent* Component)
{
check(Component->GetOwner() == this);

// Note: we do not mark dirty here because this can be called when in editor when modifying transient components
// if a component is added during this time it should not dirty. Higher level code in the editor should always dirty the package anyway
const bool bMarkDirty = false;
Modify(bMarkDirty);

bool bAlreadyInSet = false;
OwnedComponents.Add(Component, &bAlreadyInSet);

if (!bAlreadyInSet)
{
if (Component->GetIsReplicated())
{
ReplicatedComponents.AddUnique(Component);

AddComponentForReplication(Component);
}

if (Component->IsCreatedByConstructionScript())
{
BlueprintCreatedComponents.Add(Component);
}
else if (Component->CreationMethod == EComponentCreationMethod::Instance)
{
InstanceComponents.Add(Component);
}
}
}`So it is possible for the OwnedComponents set to not contain all Instanced components that the actor has, it’s also possible (if unlikely, you’d have to call both Add() functions given above) for the InstanceComponents array to contain duplicates, which appears to be against the design.

That first point is the one that I wanted to highlight though. I would expect the various get components / for each component etc functions on the actor to be guaranteed to access all associated components. Could you perhaps clarify the expectation here? Is there a use case for InstanceComponents not being a subset of OwnedComponents?

Thanks!

>That first point is the one that I wanted to highlight though. I would expect the various get components / for each component etc functions on the actor to be guaranteed to access all associated components.

That is the intent. Use AddComponents to achieve this. AddInstanceComponents was added in 4.7 and was just introduced to allow the InstanceComponents array to be moved to private. Its original usage was by the SCSEditor.

>Is there a use case for InstanceComponents not being a subset of OwnedComponents?

At edit time, when a tool is just setting up the Actor in a manner that is appropriate for saving.

Thanks, appreciate the explanation!