Destroying spawned objects OnDestroy in Editor

This seems like it should be simple to find the answer for, but here it goes:

My goal: I want to be able to drag my TileGrid class (extends AActor) onto into the viewport, and for it to spawn some Tile objects. If I move the TileGrid object, I want the others to follow (with an offset location), but each object can also be moved individually when selected. Then when I delete the TileGrid object, I want all of the spawned Tile objects to be destroyed as well.

My solution to spawning the objects:

FActorSpawnParameters fp;
fp.Owner = this;
AActor* ATile = this->()->SpawnActor<AActor>(TileClass);			
ATile->AttachRootComponentToActor(this, NAME_None, EAttachLocation::KeepRelativeOffset);

This works as expected: I have it inside the constructor (with the bAllowDuringConstructionScript flag set on fp) and I have it inside the PostEditChangeProperty for when the TileBaseClass gets changed in the editor.

The problem is when I come to delete the object in the editor. The children are detached and left hanging around afterwards and I’m at a loss as to how to make them also disappear.

  • I tried storing an array and going through it in the OnDestroy function, but the array was empty when I got there.
  • I tried accessing the Children array, but that was also empty in the OnDestroy function.
  • I tried using the GetAttachedActors() array, also empty at OnDestroy.

I’ve just gotten wind that the solution, if I were using blueprints, might involve binding the Tile objects to be notified when the TileGrid object gets deleted. But I’m not 100% how I’d do this in blueprints, let alone using the UE4 code.

Thanks for taking the time to respond. I did actually try this earlier:

void AUGTileGrid::BeginDestroy()
{
	UE_LOG(LogTemp, Log, TEXT("*** BeginDestroy() entered. ***"));	

	TArray<AActor*> TheAttached;
	this->GetAttachedActors(TheAttached);
	UE_LOG(LogTemp, Log, TEXT("The attached.Num is %d"), TheAttached.Num());
	UE_LOG(LogTemp, Log, TEXT("this->Children.Num is %d"), this->Children.Num());
	UE_LOG(LogTemp, Log, TEXT("Tiles.Num is %d"), Tiles.Num());

	Super::BeginDestroy();
}

Which simply output the following:

 LogTemp: The attached.Num is 0
 LogTemp: this->Children.Num is 0
 LogTemp: Tiles.Num is 0

Despite it being clear that there was an attached actor (which was now unattached of course).

Try overriding BeginDestroy() which is first function called when object is marked to be destroyed, at that point properties should be accessable

Try Destroyed then

I thought “Well, if BeginDestroy() is showing empty arrays, Destroyed() certainly will!”.

How wrong I was. For some reason, in the editor at least, Destroyed() is being called before BeginDestroy(). Which doesn’t make a whole load of sense to me. Does anybody know if this is intended behaviour? Or editor-viewport specific?

^^ This!!! This needs to be brought to attention for anyone strugling with on destroy cleanup process.

Quoted from OP’s Comments to shadow river’s answer

For some reason, in the editor at least, Destroyed() is being called before BeginDestroy().

So the answer is you do your destroy other actors and stuff in an overridden Destroyed() function