I hear you, and am facing a similar problem. My current idea is to utilize the an Initializer Object, Basically a class or struct that contains an array of structs that are created when the actor or object is spawned. It can be created and set in the editor, in the defaults of an object, or on an instance of an object.
Basically the structs contains a UClass object that I can set for the type of object to spawn, then various properties to set when the object is spawned.
Granted to me it still feels crude, and I am still figuring out how to create it so that the structure does not “stick around” for the life time of the object. So Basically what you do is you have say “MyActor” which is what ever actor, pawn, or thing you want it to be. Then “MyInstancedObject” which is the core class of the thing you want to add to your actor at run time. Then “FMyInstancedObjectData” which is a struct that contains a UClass specifier for spawning and a bunch of properties that you set when your actor is spawned. Then “MyFactory” is responsible for a TArray of FMyInstancedObjectData structs that is a property with the specifiers “editinline” this should allow you to add new instances of the FMyInstancedObjectData To the Factory assigned to your actor IN THE EDITOR. Then in the “MyActor” you put a property for “factory” with the specifier “Instanced” which (if I am reading the documentation correctly) will crate a unique instance of the MyFactory object when you create the class (you may need to use the FObjectInitializer to instance the MyFactory object)
Anyway those are my thoughts, I have not gotten around to testing this but this is what I plan on doing. I’d love to see a better method if one exists, especially one that is more editor integrated such as creating a custom window or panel for your NPCs.
My current problem with the DataTable is that you cannot set UClass objects in the editor. You will have to use a path to the blueprint instead.