Python in Unreal Engine — The undocumented parts

Filip Sivák
4 min readJan 22, 2022

--

Some python features are not documented at all. Such as declaring struct or enum.

There are many tutorials on how to use python in Unreal Engine, however, they are often missing the interesting parts:

  • how to get a subsystem in python
  • how to return struct or array from a python function
  • how to pip install package into Unreal Engine

In this article, I cover the more obscure examples that I had to find out the hard way. Let me start with simple things and gradually progress to more interesting stuff.

I also have to remind you that python (as provided by PythonScriptPlugin) is not usable a cooked game! You can use python only for your editor tools or in projects that do not require cooking.

Single-purpose script — How to automatically import a whole folder of assets

Create script UEProject\Content\Python\python_import_fbx.py and use the following code:

import unreal
from pathlib import Path
IMPORT_DIR = Path(r"G:\path\to\fbx_folder")
assert IMPORT_DIR.exists()
tasks = []
for fbx in IMPORT_DIR.glob("*.fbx"):
asset_import_task = unreal.AssetImportTask()
asset_import_task.filename = str(fbx)
asset_import_task.destination_path = '/Game/Geometry'
asset_import_task.automated = True
tasks.append(asset_import_task)

asset_tools = unreal.AssetToolsHelpers.get_asset_tools()
asset_tools.import_asset_tasks(tasks)

You can import any assets this way, not just FBX files. You can also switch “automated” to False to invoke an import dialog.

You can run a python script using the command “py”. This means you can also run python script in Movie Render Pipeline before or after render using Start/End commands

How to run python automatically on engine startup

Put file named init_unreal.py in any Content\Python folder and it will be run on startup of the engine.

How to get a reference to a subsystem in Python

Subsystems are accessed via special nodes in blueprints
aes = unreal.get_editor_subsystem(unreal.AssetEditorSubsystem)

Defining struct, enum and class in python and use it in a blueprint

In the following example, we can see how to define a struct, enum, and Blueprint Function Library to be usable in a blueprint. The enum and struct can be used throughout a blueprint as a type of variable.

MyPythonFunction declared lower, returning custom struct PythonUnrealStruct (output pin splitted)

Some important things to note:

  • When declaring ENUM, you should use values of numbers from 0 to N. You can skip numbers but Unreal expects that there is always an enum value of 0.
  • Struct must inherit from unreal.StructBase or its subtype. It didn't work from me if I inherited from the unreal.Struct. Fields in a struct are defined by unreal.uproperty
  • Don’t forget to mark your blueprint library functions as static

In order for the function or type to be usable in blueprints, they must be either defined in or imported by Content\Python\init_unreal.py file. As init_unreal.py will be called on startup of the engine, making the definitions available to blueprints.

Using C++ types in python

If you declare a BlueprintCallable (or BlueprintPure) function: UBlueprintLibrary::MyCppFunction(int Num, TArray<FVector> Positions)

You can access it in python as:

unreal.BlueprintLibrary.my_cpp_function(num, pos)

Note that the name of the function is now in a snake_case (https://en.wikipedia.org/wiki/Snake_case)! You can pass it an ordinary python list of vectors and the list will be converted to TArray internally.

How to use pip install with Unreal Engine

Method 1 — Using a command line

Using Unreal Engine python library, you can run the pip module:

C:\Program Files\Epic Games\UE_4.27\Engine\Binaries\ThirdParty\Python3\Win64\python.exe -m pip install numpy

Method 2 — Installing required packages automatically on Engine startup

Installing directly in Unreal Engine

This option is great when you work in a team and you don’t want to force your colleagues to “pip install” every time you update something. Use the following code in init_unreal.py, so it’s run on Unreal startup and installation happens transparently.

How to call python function through REST API

Remote Control API plugin (https://docs.unrealengine.com/4.27/en-US/ProductionPipelines/ScriptingAndAutomation/WebControl/QuickStart/)allows you to call functions remotely through REST from a different computer, phone, or tablet. You can call existing blueprint functions, but also your own C++ and Python types. Here is how to call python:

Having a Python file \Project\Content\Python\remote.py and installing the type RemoteClassto the engine by running the command: py remote.py (in the Output window):

import unreal@unreal.uclass()
class RemoteClass(unreal.BlueprintFunctionLibrary):

@unreal.ufunction(static=True)
def remote():
print("Hello from remote!")

You can send a PUT request with the body:

{
"objectPath": "/Engine/PythonTypes.Default__RemoteClass",
"functionName": "remote"
}

The result is the text "Hello from remote!" logged into the Output window.

How to call python asynchronously from C++

FString PythonCommand(TEXT("SomePythonFunction()"));Future = FFunctionGraphTask::CreateAndDispatchWhenReady([=]
{
IPythonScriptPlugin::Get()->ExecPythonCommand(*PythonCommand);
});

Debugging python running in Unreal Engine

You can debug the python code running in embedded python in the engine! The official tutorial from EPIC is a block comment at Content\Python\debugpy_unreal.py

Python internals

The integration is done in the plugin PythonScriptPlugin. Python decorators such as ustruct, uenumand function are defined at PythonScriptPlugin\Content\Python\unreal_core.py Those are then calling functions defined in C++ and accessed through the module _unreal_core

--

--