I have thought about this too before.
For example, if I have a weapon model I want my character to hold, I don’t want to specify just a skeletal mesh. A lot of examples have like a UPROPERTY of what the mesh is for a weapon, but what if I want an entire hierarchy of components, like a particle system, a light, sounds, etc…
And yeah, I ended up just creating actual actors and attaching child actors. It gives the most power.
I do that for many things, like even in our game’s decal system. My weapon impact doesn’t just specify some decal texture to use. I specify an entire actor. That way when my weapon impacts, the impact actor takes care of what sound effect to play on impact by having a sound component. It has the decal component and particle effects, and whatever else. If I want it to look like some arrow periced my target on impact it also has a static mesh for an arrow. Maybe there’s even a dynamic light if there’s an explosion or some fire left behind. And the actor can have custom logic added to make different parts of it fade out after some time, or not spawn certain things depending on quality settings.
This way my impact system goes from something like this:
UPROPERTY(EditAnywhere, ...)
UMaterialInterface* DecalMaterial;
UPROPERTY(EditAnywhere, ...)
USoundCueue* ImpactSound;
UPROPERTY(EditAnywhere, ...)
UParticleSystem* ImpactEffect;
UPROPERTY(EditAnywhere, ...)
UStaticMesh* ImpactMesh;
etc... Lights? Looping sounds? Looping particle systems? etc...
It’s now just as simple as specifying which actor to spawn and that actor takes care of all the effects an artist can imagine wanting to spawn.