How to detect when actors/components are added to a level or blueprint

If I have an actor in my level that manages certain things, can I have it detect when actors/components are added/removed in editor and track them?

I’m currently doing a scan for all actors/components every time one of my levels is streamed in for a procedural level generator which I think can be avoided if this is all precached ahead of time in an actor that exists in the level.

For example, if I want to know where all the doors are in my level, I’d like to have an actor that comes preloaded with references to all doors, instead of iterating over everything in the level and checking if it’s a door.

It would be great if I could detect this in the blueprint editor as well. If I add a certain type of component I want to store a reference to it and maybe store it in some other data structures.

Why not the other way around, tell your ‘master’ actor when there is an update. I am a door, my position is this, add me to the array or map.

I think that is in fact the right way to go. In game, I’d use something like BeginPlay or OnRegister but this is in editor. I haven’t found clear docs on how these things work in editor. Like when I place a new component, is there some kind of way to talk to the editor and have the editor find me an instance of another actor and set things up?

At the moment, all my code runs at the start of the game, but I’d like to have all of my datastructures prepopulated ahead of time.

I’m doing this for a procedural level generator so I don’t always even have instances of these actors existing in the world yet. I’m currently creating fake versions of these actors and streamed levels that exist in a second world separate from the main world, and deleting them when the level generator is done. It would be great if all of this data was already precomputed on the CDO if possible, or saved in an actor that exists in a level.

Oh I did manage to find some useful info under Remarks on the AActor docs:

This thread lists pretty high in a search results, so I’ll quickly add a possible answer:

I believe the best solution for such case is overloading UActorComponent::InitializeComponent

/**
* Initializes the component.  Occurs at level startup or actor spawn. This is before BeginPlay (Actor or Component).  
 * All Components in the level will be Initialized on load before any Actor/Component gets BeginPlay
 * Requires component to be registered, and bWantsInitializeComponent to be true.
*/
virtual void InitializeComponent();

For this to work the UActorComponent:bWantsInitializeComponent must be set to true in the constructor.

/** If true, we call the virtual InitializeComponent */
uint8 bWantsInitializeComponent:1;

(this one only works for Components of course)