at least as of UE 5.2.1:
You cannot rely on setting the plugin’s loading phase to PostEngineInit
to guarantee the existence of GEditor
inside StartupModule()
!
Plugins will load at the earliest loading phase in their chain of dependencies, meaning the actual loading phase used by a plugin can become earlier than the loading phase set in the .uplugin settings!
i.e. GEditor
may not exist (yet) when the plugin is initialized.
Example
- Suppose we have a
Plugin A
which loads inDefault
. - A new
Plugin B
is added that depends onPlugin A
.Plugin B
loads inPreDefault
. - Now
Plugin A
will be loaded inPreDefault
, along withPlugin B
. Plugin A
may suddenly and mysteriously start breaking as a result.
This can be rather surprising and is hard to figure out what’s wrong if you weren’t thinking about Plugin A
when changing Plugin B
’s loading phase or dependencies.
Workaround
A more reliable way to access GEditor
on module startup is to listen on the PostEngineInit
delegate explicitly using FCoreDelegates::OnPostEngineInit
.
FCoreDelegates::OnPostEngineInit.AddRaw(this, &FMyModule::OnPostEngineInit);
Do note that if the loading phase is PostEngineInit
, then the OnPostEngineInit
delegate will have already fired! so your OnPostEngineInit
callback will not be executed in that case.
If you’re not worried about this, you can simply use an earlier loading phase, e.g. "Default"
and always use the delegate, as the loading phase cannot get later than what’s specified in .uplugin
, only earlier, IIUC.
void FMyModule::OnStartup() {
// wait for GEditor to be ready
FCoreDelegates::OnPostEngineInit.AddRaw(this, &FMyModule::OnPostEngineInit);
}
However if you want to ensure fewer surprises when changing loading phases in the future, you can wait for GEditor
if it’s missing, or run your init immediately if GEditor
is already around:
void FMyModule::OnStartup() {
if (GEditor) {
OnPostEngineInit(); // GEditor ready, init immediately
} else {
// wait for GEditor to be ready
FCoreDelegates::OnPostEngineInit.AddRaw(this, &FMyModule::OnPostEngineInit);
}
}
With this you should be able to adjust dependencies and loading phases without creating as many load order issues in other plugins.
edit: Also see this good suggestion from @Engelard: