Startup Script Management
going beyond the init_unreal.py file
Covered in Organizing Startup Scripts, my init_unreal.py
file usually looks something like this:
from recipe_book import startup
startup.run()
The startup
module is where I organize everything I want to happen on Unreal startup, split into two main sections:
Pre Startup - Python code that can is safe to run immediately the moment Python is loaded
Examples might include:
Initializing a custom Python logger
Register metadata names
Environment setup, such as fixing the sys.path if required as part of a pipeline
Initialize Python classes other code might rely on
Loading external config data or packages
Post Startup - Python code to run after the Editor is fully loaded
I consider this step ready once the Asset Registry has scanned the entire UE Project
Examples might include:
Initializing the Python-defined Editor Menus
Opening Editor Utility Widget startup tools (such as a homepage tool listing all ShotGrid tasks)
Running any tools that rely on the Asset Registry
Waiting for the Asset Registry
The main separator of my Pre and Post Startup logic is whether the Asset Registry has finished loading the Unreal Project.
Thankfully, there is an easy enough function to reference on the Asset Registry: is_loading_assets()
# the Asset Registry
asset_registry_helper = unreal.AssetRegistryHelpers()
asset_registry = asset_registry_helper.get_asset_registry()
print(
f"Is Asset Registry Ready? "
f"{'no' if asset_registry.is_loading_assets() else 'yes'}"
)
We can use this with register_slate_post_tick_callback() to track the Asset Registry on startup to wait until it's ready:
asset_registry_helper = unreal.AssetRegistryHelpers()
asset_registry = asset_registry_helper.get_asset_registry()
startup_id = None
def wait_for_asset_registry(ignore=None):
"""Wait until the Asset Registry is ready before continuing"""
if asset_registry.is_loading_assets():
print(f"Still waiting on the Asset Registry...")
return
print(f"Asset Registry is ready!")
# We can now remove the callback and continue
global startup_id
unreal.unregister_slate_post_tick_callback(startup_id)
# do the thing or call the next function here
pass
# start the callback if not already running
if not startup_id:
startup_id = unreal.register_slate_post_tick_callback(wait_for_asset_registry)
And here's an example of running this during startup on a large project:

Full Startup Example
building off of the wait_for_asset_registry function, my startup module generally has the following in it:
A dedicated function that contains all Pre Startup commands
A dedicated function that contains all Post Startup commands
The Wait For Asset Registry callback function, which calls Post Startup when complete
A run() function that calls Pre Startup and sets up the Wait For Asset Registry callback
the
run()
function is the main entry point in this module, and is the only function that should be called externally
And here's what that code looks like:
asset_registry_helper = unreal.AssetRegistryHelpers()
asset_registry = asset_registry_helper.get_asset_registry()
startup_id = None
def on_pre_startup():
"""Scripts that can run immediately on Editor Startup"""
print("Running Pre Startup Scripts")
# Import and run Pre Startup scripts here
def on_post_startup():
"""Scripts that should run after the Asset Registry is fully loaded"""
print("Running Post Startup Scripts")
# Import and run Post Startup scripts here
def wait_for_asset_registry(ignore=None):
"""Wait until the Asset Registry is ready before continuing"""
if asset_registry.is_loading_assets():
print(f"Still waiting on the Asset Registry...")
return
print(f"Asset Registry is ready!")
# We can now remove the callback and continue
global startup_id
unreal.unregister_slate_post_tick_callback(startup_id)
# run Post Startup
on_post_startup()
def run():
"""run Pre Startup and then schedule Post Startup"""
# Pre Startup can run right away
on_pre_startup()
# Schedule Post Startup
global startup_id
if not startup_id:
startup_id = unreal.register_slate_post_tick_callback(wait_for_asset_registry)
else:
unreal.log_warning("Unreal Startup has already been run!")
In this setup, the only thing that needs to be updated / maintained are the on_pre_startup()
and on_post_startup()
functions - we shouldn't need to ever touch run()
or wait_for_asset_registry()
.
Last updated