[Python] - calling method on main game thread from current thread

[Unreal Python]
How can I launch specific my_method() from current thread in main game thread?

I need to get some data from asset library, but this can be done only in (main) game thread. I found this topic: Main thread and thread - #2 by manoelneto but no
CreateAndDispatchWhenReady or AsyncTask methods are avaliable in python.

I also found unreal.AsyncRegisterAndExecute class unreal.AsyncRegisterAndExecuteTask — Unreal Python 5.0 (Experimental) documentation , but I am not sure how to use it properly.

Or am I totaly wrong and running methods on game thread from current thread is just not exposed in python yet?

Thanks for answers.

1 Like

Hi hajnis_work !
Please tell me, did you execute your function in game thread UE 5 with python? I can’t find any information about this opportunity, but i really need it. I will be very grateful for you if you share your experience in this question if you have it. Thank you!!!

Hi @anonymous_user_58fd81f3,

Short answer: Yes.

Long answer:
You have to expose new function for python, which will then run a custom python code (string code) on main thread. The way I did it is not the best one ( i guess), but its the only way I could find.

First I created an editor c++ plugin ( as everyone should do, because the later distribution is easier…) called PythonExtension. In the plugin there are two important files. Public/PythonExtension.h and Private/PythonExtension.cpp ( if they are not here, create them and then regenerate project solution (how to generate solution)

In PythonExtension.h file, new blueprint/python callable method was created:

	 * Makes possible to run python script on the main thread from any other thread.
	 * @param pythonCode - input python code in form of a string example: "print('Hello Unreal')", can be multiline.
	UFUNCTION(BlueprintCallable, Category="PythonExtension")
	static void LaunchScriptOnGameThread(FString pythonCode);

PythonExtension.cpp is simple as well:

#include "PythonExtension.h"
// its important to include IPythonScriptPlugin.h as well
#include "../Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Public/IPythonScriptPlugin.h"
#include "Async/TaskGraphInterfaces.h"
#include "Microsoft/MinimalWindowsApi.h"

void UPythonExtension::LaunchScriptOnGameThread(FString pythonCode)
	FGraphEventRef Task = FFunctionGraphTask::CreateAndDispatchWhenReady( [&]()
	}, TStatId(), NULL, ENamedThreads::GameThread);


You also have to add PythonScriptPlugin into PrivateDependencyModuleNames in your Build.cs ( so you can include IPythonScriptPlugin.h in PythonExtension.cpp) and also to you .uplugin so Unreal knows its using the PythonScriptPlugin.


	"FileVersion": 3,
	"Version": 1,
	"VersionName": "1.0",
	"Description": "",
	"Category": "PythonExtension",
	"CanContainContent": true,
	"IsBetaVersion": false,
	"IsExperimentalVersion": false,
	"Installed": false,
	"IsHidden": false,
	"EnabledByDefault": true,
	"Modules": [
			"Name": "PythonExtension",
			"Type": "Editor",
			"LoadingPhase": "Default"
	"Plugins": [
			"Name": "PythonScriptPlugin",
			"Enabled": true

PrivateDependencyModuleNames.AddRange(new string[] {"Core", "CoreUObject", "Engine", "PythonScriptPlugin",});

Now when You build editor, you should be able to call this from python console:

import unreal
unreal.PythonExtension.launch_script_on_game_thread("print('hello from main thread')")

Now the python part:
Our launch_script_on_game_thread() method takes python string code as an input argument so it will be nice to have some method, which will read another method as input and create string from the code inside:

def run_on_main_thread(function):
    This will launch input function on unreal main game thread
    func_lines = inspect.getsourcelines(function)[0][1:]

    code_in_string = ""
    # remove blank spaces at start and end in every line
    for line in func_lines:
        code_in_string += line.strip() + "\n"

And final touch - calling the function somewhere in your python thread:

# this is somewhere inside python class..
        def import_main_thread_prep(self):
            This function is launched by our c++ PythonExtension module on Main Thread.
            It is the only way how to import asset if working on different thread.

            # since this is run on different thread, we have to repeat the import statements for our import_manager
            # in c++ source code we simulate this like if person writes following three lines of 
            # code into python console
            from your_custom_module import YourClass
            # YourClass could be singleton, so its quite easy to init data on it and then get them without using arguments
            my_custom_singleton_class = YourClass()
            my_custom_singleton_class .call_ue_asset_methods()

Thats it. It will probably take you some time to tinker with it, but once you grasp how it works, it should be pretty easy to do your own stuff on it.

PS: its also possible, that in code above there are some mistakes as I had to change my code in order to simplify it for you. If you find a mistake, please feel free to respond so I can change it.