How can I automatically spawn an actor from a plugin in Blueprints (or C++) as the plugin gets loaded?

I tried this:

but since the Initialize Plugin event runs on a subsystem, there is no access to SpawnActor. It has a GameInstance but GetWorld is inaccessible and even if it were accessible, SpawnActor wouldn’t show up.

I tried creating a custom GameInstance in my plugin, but I can’t find a resource for how to use it. On a main project I would just change the DefaultEngine.ini to point it at the custom GameInstance, but in a plugin, I’m not sure. I followed the comment by Nofyt at the end:

The goal is to spawn a controller actor I’m making automatically when the game is ran. The actor is always on and running code on tick.

I’d appreciate any help into this!

Plugins can be loaded before a World / Level is loaded, and worlds/levels may unload/reload without the plugin being notified, so what you say you want to do wouldn’t work out well.

Why does your code need to be an Actor? Does it really need to be an Actor in every world? Even if that world is just, say, a “welcome to the game” menu?

In general, if you need a particular actor in a particular world, you add it to the world. And if you don’t need it, you don’t add it.

If your plugin needs to “run code on tick,” it can add itself as a tick listener, even without being an Actor. See for example FTickFunction for a place to start.

The controller itself doesn’t necessarily need to be an actor, but it would need to be able to spawn actors based on user inputs. The controller has to be in every level, so instead of manually adding the controller in every single level one-by-one, I thought that maybe there was a way to do it automatically.
I have the GameInstanceSubsystem automatically being called when the plugin loads at runtime, so that gave me hope, but if it causes more problems than it’s worth, I could find another work around.
Maybe the code that creates the controller could be in the game mode.
Maybe I can still use the subsystem but spawn the code in C++ where I do have access to GetWorld()->SpawnActor; after checking if the game has started somehow.

I have a project where I need to do something sort of similar – it’s a tactical RPG engine, and I need to create a “Grid Manager” object for any loaded level.

My approach was to simply subclass AWorldSettings; I created an AGridWorldSettings and then set that as the default world settings class for my project. When the level loads, the world settings object is right there automatically (because every world has a settings object). And while the settings object doesn’t get a BeginPlay event, it does get NotifyBeginPlay (which is where it tells all the actors in the level that they should begin play). So I just overrode NotifyBeginPlay(), set up my grid manager, and then call the superclass implementation of NotifyBeginPlay() at the end.

I could probably also have done it in the game mode – likely in StartPlay – but I chose to use the world settings for other reasons.

(Those reasons being that since the world settings now were subclassed, I was able to put the actual settings the grid manager needed for a given level right into the level’s settings. As a result, my editor module’s ‘grid layout’ mode saves what you configure right into the level’s AGridWorldSettings, and the runtime module reads those parameters out of the settings in order to instantiate the level’s grid manager. )

This may honestly not be the best approach – there may be a better one I haven’t considered! – but it works very well for my specific use case.

ULocalPlayerSubsystem is initialized every time a Game World executes BeginPlay()

I’m pretty sure you don’t ACTUALLY want that. For example:

  • The “start game” menu is typically a level. You probably don’t want to spawn those actors in that level.
  • Each sub-chunk of a world in “level streaming” setups, is a separate level, You probably don’t want to have multiple instances of that controller/spawner just because you’re using sub-level streaming.

Without letting us know what your specific actors do, it’s hard to figure out what the best solution would be, but “add a necessary actor to each level that needs it” is generally the first place to start. You could also make it a Subsystem, or perhaps part of a GameMode; both of those have appropriate hooks to create objects where and if needed.

Honestly, this is the other reason I did my thing via world settings; for any level I don’t need to instanciate a grid manager for, I just change the world settings back to the normal AWorldSettings and hey, check it out, no grid manager.

(Plus, as a bonus, the editor module sees that it’s not a grid-enabled level and just disables the grid manager mode for that level.)

…admittedly, I did not consider that aspect of things in my world-settings approach. (Though, it’s a moot point for that specific project, since the tactical RPG has bite-size battle maps regardless and thus makes no use of level streaming.)

All good points. In my original scheme of using GameInstanceSubsystem, the code would run one time only when the plugin gets loaded, so issues like level streaming wouldn’t be a problem. Code being present during a menu level would also not a big issue. That said, the quoted text made me think of what the actual owner of the code should be. I’m now considering a different approach.
Part of what I’m trying to accomplish is add this controller to a plugin so that it’s easy to use in multiple projects. Ideally the setup in each project would be minimal so an automatic solution seemed enticing.
Because the controller does listen to user inputs, the code should actually be in the Player or PlayerController.
Thanks for the input to all.