Download

Why is AActor::Children null when the actor has children?

I have an AActor class ARoom, whose only job is to monitor the objects and people inside of it. Every prop in the room (chairs, tables, lightbulbs, etc) is a child of its Room, so I thought I could get a reference to a room’s contents just by doing this:


//Room.h:

	UPROPERTY(VisibleAnywhere)
	TArray<AActor*> actorList;

//Room.cpp:

void ARoom::BeginPlay()
{
	Super::BeginPlay();
	//Spawn some dudes
	//mySpawners = this->GetComponentsByClass<UBaseSpawnNode>();

	//UActorComponent* temporaryComponentList; = GetComponents();
	
	actorList = Children;
}

According to https://docs.unrealengine.com/latest/INT/API/Runtime/Engine/GameFramework/AActor/Children/index.html, Children should consist in every actor childed to this actor, but whenever I run this actorList is null, even when I have numerous objects childed to the room. Am I doing something wrong, or was Children just not intended to be used this way?

I encountered the same issue - for some reason, children set in the editor are not accessible.

That’s downright strange… is there a simple way to obtain children set in the editor? A lot of my workflow is based around the idea that a level designer builds a space however he wants, and as long as all the props that NPCs can use are childed to an ARoom actor, NPCs can always query ARoom->PropsList to see what’s available for them to use.

Haven’t needed the transient property yet, would that affect this?



UPROPERTY(transient)
TArray<AActor*> Children;


Here’s an alternative, but it gives you the children in reverse for whatever reason.



TArray<AActor*> actorList;
GetAttachedActors(actorList);

for (AActor* actor : actorList)
{
	UE_LOG(clog, Log, TEXT("children: %s"), *actor->GetName());
}


Resulting log:



clog: children: SpawnProxy_23
clog: children: SpawnProxy_22
clog: children: SpawnProxy_21
clog: children: SpawnProxy_20
clog: children: SpawnProxy_19
clog: children: SpawnProxy_18
clog: children: SpawnProxy_17
clog: children: SpawnProxy_16
clog: children: SpawnProxy_15
clog: children: SpawnProxy_14
clog: children: SpawnProxy_13


Which is accurate to what the editor has, albeit reversed.

Oh hey, that works!! That is awesome, thank you… I’m still not quite sure why Children doesn’t like stuff added in the editor, but GetAttachedActors does the trick perfectly. :slight_smile:

No worries. I was thinking about it a bit and maybe there’s a better alternative especially if you need more control… children of the AActor add / remove themselves from the Children TArray when they’re spawned or destroyed, you could consider doing something similar such as… excuse the partial pseudo / incorrect code as I’m short on time:

Parent:

TArray<AActor*> childActors;

Children:

OnConstruction perhaps
GetRootComponent->GetAttachParent->GetOwner (I think this order is correct off the top of my head - it’s meant to get the object’s parent in the level) -> Cast to whatever parent class is (probably don’t want to do this while the game is running unless if there is many children) -> childActors.Add(GetRootComponent())

then OnDestroy, remove from array, if needed

I only suggest it because it doesn’t give you a reversed array. Or you could reverse the array, was just thinking of an alternative that might make dealing with the result easier such as having the children add themselves or not based on conditions and so forth.

In this one exact use case I have the luxury of not worrying about array order, since all the system needs to worry about is the presence or absence of the nodes, but I like your solution if retaining ordering is important… I think it’s one of those things that’s going to end up being really case-specific. I do think GetAttachedActors() is slightly “cleaner”, in that relying on the child to notify the parent couples the two classes just a tiny bit, but I can see a lot of cases where the coupling is worth maintaining a non-reversed array.