UE4 has supported Python scripting within editor builds for a number of versions now. In versions 4.23 and previous, you had the ability to derive your Python classes from native engine classes and override functions that were previously defined in that C++ class. This allowed you to write custom scripts in Python and have Blueprint nodes interact with them. However, one thing that was missing was the ability to expose Python only defined functions as callable Blueprint nodes. As of UE4 4.24, you will be able to expose Python class methods to the Blueprint VM without having to touch C++ first. This is a great tool for those that don’t know C++ but want to be able to make automation Python scripts that act as Blueprint Function Libraries.
What is a Blueprint Function Library? It is a collection of functions that Blueprints can use. Often, these are sets of functions that bridge between Blueprints and a native layer that does not have a UObject based API (AR/VR). The libraries are never instanced, so all methods are expected to be static and not contain any properties. Because they are more of a concept than a class hierarchy, there are no base methods to overload. This is why being able to define new class methods in Python that are exposed to our UObject API is needed. Prior version support was very close to working, but some small issues needed to be addressed.
The Blueprint VM operates on UE4’s reflection system in order to be able to call functions or access properties. The Python integration automatically generates the corresponding reflection data for Blueprints to use when the Python code is properly decorated. The small bit of Python code below is a Blueprint function library that illustrates how to decorate a class and methods.
First thing is a decoration telling UE4 that the Python class should be exposed to Blueprints. The Python class must derive from a UObject derived class, such as AActor or UBlueprintFunctionLibrary. Note that we expose the classes to the Python environment via the “unreal” namespace and remove the native classes’ prefix, just like in Blueprints.
The next step is to decorate each function that you want exposed as a Blueprint node. Since there is not an underlying native class to pull from, this step provides all of the information the integration needs to make calls to those methods. If you get something wrong in this step, the error messages will show up in the Output window in the editor. These errors can happen at either loading of the Python code or when the Blueprint code tries to execute the Python method. The latter should only happen if the decoration data exposes the parameters or return type incorrectly.
Let’s take a look at the simplest example, the LaunchMaya method. It doesn’t take any parameters and doesn’t have a return value so the only decorations present are the labeling it as static and the meta data needed to place the Blueprint node in a specific Category. The image below shows this in context of adding a new Blueprint node.
UE4 needs to know the underlying data types for parameters and return types. It creates the corresponding wrapper UProperty types underneath the covers. If the type returned from the Python code does not match the decorated code, there may be a runtime error if it can’t convert it. It’s always best to make those match correctly. The same is true for UE4 sending parameters to the function. It might be able to convert, but it’s best not to rely upon that. In our sample code, you can see two examples of return values being specified and two examples of passing parameters to a function. When specifying the types, make sure to use the Python names for the type and not the UE4 names. The two images below are from Editor Utility Blueprints showing use of each category of functions.
If you are creating automation tasks, using Editor Utility Blueprints is an easy way to orchestrate Python processes using a Blueprint graph. For instance, the top graph could look at the currently selected asset, export it to FBX, and launch Maya so the artist can edit it. If you are not familiar with Editor Utility Blueprints, they are Blueprints that have a Run event and can be run from within the Content Browser or from a UI interaction. The images below show the creation and invocation of the Maya flow shown in the image above.
One thing to note is that you must have the Python code loaded as part of the editor startup process or you will see errors in your Blueprints as shown below.
To recreate the samples you’ve seen above, you’ll need to wait for version 4.24 to ship or you’ll need to pull source from GitHub. I mostly work in the XR branch, so the the extra fixes you need for Blueprints to see your functions has been merge to there (Dev-VR branch).
Some extra resources are listed below: