Using Python Scripting in Unreal Part I : Setup and First Script
Table of Contents
Python Scripting in Unreal - This article is part of a series.
Setup and First Script #
When to use it. #
Python scripting is a easy and efficient way to extend Unreal Engine abilities. Based on my usage I would recommend using Python scripting when:
- We prefer to use Python over C++ (note that Python scripts aren’t as fast as C++ and should not be used in core gameplay).
- We need editor time tool using external libraries that python may provide.
- We need to use some python based libraries.
- Python libs are more robust and performance isn’t huge issue.
This means I would suggest using python scripting mostly in Editor time (time when we work on editor) to generate content (for instance using PCG), generating some data for analysis, importing and exporting data, or any other tools that may use robust python pros like data analysis, text manipulating or web connection. If you want to use python during Play time (during playing cooked build) I would recommend to use it only async but that(Play time python script calling) is not supported currently.
Note that I am not aware of most python libraries that can be really useful so don’t limit your ideas by my examples of usage.
Setting it Up #
To setup Python in unreal we need to complete simple step list:
Enable Python Scripting plugin #
- Firstly we are creating some basic project. I have chosen ThirdPerson Template with base in C++(C++ base would be recommended for this blog)
- Then we enable Python Plugin in by selecting
Edit > Plugins > Python Editor Script Plugin
, after enabling it will cause editor to ask for restart. To it to be able to proceed to next step - After this step we should enable Python Developer Mode in editor settings. To do this we can simply tick box in
Edit > Editor Settings > Plugins > Python
and tick developer mode checkbox. You can simply typeDeveloper Mode
in search bar too. Checking it make editor to ask for restart let do it. - We should have Python enabled and ready to work with, to confirm if
Developer Mode
which makes writing python ue5 scripts easily we can check if in pathIntermediate\PythonStub
we have fileunreal.py
this file contains unreal bindings for python and regenerate every time we open Editor not when we refresh project c++ files!
Create friendly environment #
For our quality of life we should setup some python IDE, you can go with whatever IDE you like, I will go with VsCode
. I will not go over installing VsCode as this should be straight forward and there is a lot of tutorial for it.
In VsCode we should install Python and Pylence extensions.
Then we will create our first python script file, the cool thing is that we can choose whatever path we want as we will be providing Unreal it path. So I will create new folder only for python scripts (this is only to show we can, usually in work or project you want to keep in source versioning system).
After creating new file usually Vscode will ask for python interpreter, to make it go smoothly I would recommended choosing the one unreal is providing. This one won’t be showing in Vscode and we need to find it manually. The path for interpreter should be {EnginePath}\\Engine\\Binaries\\ThirdParty\\Python3\\Win64\\python.exe
.
Then if we start typing we will see big issue. After creating simple code
import unreal #importing unreal module
unreal. #presing auto completion
We don’t get any suggestions. To fix that we need to add external unreal.py form project’s Intermediate\PythonStub
to VsCode python extension. Do do so we should go to settings and type python.analysis.extraPaths
then add our path to Intermediate\PythonStub
folder, adding path to unreal.py
won’t work.
After this we should have fully python ide support. Lets try writing some simple script and running it.
First script #
Our first script will be simple one that prints all asset names in our project
import unreal
asset_registry = unreal.AssetRegistryHelpers.get_asset_registry()
for asset in asset_registry.get_all_assets():
print(asset.get_full_name())
Of course we could define functions, classes and so one but we won’t bother with it at this time. Now we need to test it by execution.
Running Script #
We have multiple way to run it I will show you for most crucial ones:
Running it from command line #
this enables you to execute scripts when editor is closed, and this will work well with CD/CI like jenkins. To run script we can simply open terminal and type <PathToEngine>\\Binaries\\Win64\\UnrealEditor-Cmd.exe <PathToProject> -run=pythonscript -script=<PathToScript>
.
For me it looked like this:
PathToScript == D:\\UE5_proj\\PythonScripts\\ListAllAssets.py
PathToProject == D:\\UE5_proj\\PythonBlogProject\\PythonBlogProject.uproject
PathToEngine == Z:\\Games\\EpicGames\\UE_5.2\\Engine
and final command in terminal would looks like this:
Z:\\Games\\EpicGames\\UE_5.2\\Engine\\Binaries\\Win64\\UnrealEditor-Cmd.exe D:\\UE5_proj\\PythonBlogProject\\PythonBlogProject.uproject -run=pythonscript -script=D:\\UE5_proj\\PythonScripts\\ListAllAssets.py
This will run and generate either fail or success information, we are looking for information like:
LogPythonScriptCommandlet: Display: Python script executed successfully
LogInit: Display: Success - 0 error(s), 0 warning(s)
But wait, we actually didn’t printed anything !? That is correct UnrealEditor-Cmd.exe
isn’t pushing any logs that we create, our prints, logs and so on are hidden in <ProjectPath>\\Saved\\Logs\\
and we can see all assets we have in project.
small sample of it
LogPython: /Script/Engine.MaterialFunction /Engine/Functions/Engine_MaterialFunctions02/Utility/MakeFloat2.MakeFloat2
LogPython: /Script/Engine.Texture2D /Engine/EngineSky/VolumetricClouds/CloudGradientTexture.CloudGradientTexture
LogPython: /Script/Engine.Texture2D /Engine/EngineSky/VolumetricClouds/CloudWeatherTexture.CloudWeatherTexture
LogPython: /Script/Engine.Texture2D /Engine/EngineSky/VolumetricClouds/T_NoiseErosion.T_NoiseErosion
LogPython: /Script/Engine.VolumeTexture /Engine/EngineSky/VolumetricClouds/T_VolumeNoiseErosion32.T_VolumeNoiseErosion32
LogPython: /Script/Engine.Texture2D /Engine/EngineSky/VolumetricClouds/T_NoiseShape64.T_NoiseShape64
LogPython: /Script/Engine.VolumeTexture /Engine/EngineSky/VolumetricClouds/T_VolumeNoiseShape64 T_VolumeNoiseShape64
LogPython: /Script/Engine.Material /Engine/EngineSky/VolumetricClouds/m_SimpleVolumetricCloud.m_SimpleVolumetricCloud
LogPython: /Script/Engine.MaterialInstanceConstant /Engine/EngineSky/VolumetricClouds/m_SimpleVolumetricCloud_Inst.m_SimpleVolumetricCloud_Inst
LogPython: /Script/Engine.StaticMesh /Engine/EngineMeshes/Sphere.Sphere
LogPython: /Script/Engine.Texture2D /Engine/EngineResources/WhiteSquareTexture.WhiteSquareTexture
LogPython: /Script/Engine.Texture2D /Engine/EngineResources/GradientTexture0.GradientTexture0
LogPython: /Script/Engine.Texture2D /Engine/EngineResources/Black.Black
LogPython: /Script/Engine.MaterialFunction /Engine/Functions/Engine_MaterialFunctions02/Utility/BreakOutFloat3Components.BreakOutFloat3Components
LogPython: /Script/Engine.MaterialFunction /Engine/Functions/Engine_MaterialFunctions02/Utility/MakeFloat3.MakeFloat3
LogPython: /Script/Engine.MaterialFunction /Engine/Functions/Engine_MaterialFunctions02/Utility/MakeFloat4.MakeFloat4
Running it from editor #
This need only path to script:
PathToScript == D:\\UE5_proj\\PythonScripts\\ListAllAssets.py
- Open Editor
Note that we can give unreal path to scripts and that way we can forget about whole path. (Work in progress) In editor we need to two things:
- open output log -> we do this by going
window > Output log
- selecting proper command line
After this we can simply past our script path into command line and press enter. Note as we are listing all assets it may take some time!
Running form command line with editor start-up #
This is enable us to rung editor from command line and execute script on it, similar to Running it from command line
we just need terminal command.
<PathToEngine>\\Binaries\\Win64\\UnrealEditor-Cmd.exe <PathToProject> -ExecutePythonScript="<PathToScript>"
in our example that will be:
Z:\\Games\\EpicGames\\UE_5.2\\Engine\\Binaries\\Win64\\UnrealEditor-Cmd.exe D:\\UE5_proj\\PythonBlogProject\\PythonBlogProject.uproject -ExecutePythonScript="D:\\UE5_proj\\PythonScripts\\ListAllAssets.py"
After running script our Editor will turn off and results will be in log file same as in Running it from command line
.
Running form blueprint #
To quickly run command in engine from blueprint we need to create either Editor Utility Blueprint
or Editor Utility Widget
. I have chosen Editor Utility Blueprint
that is child of EditorUtilityObject
and for now I recommend you to do the same. In this blueprint we create function that can be called in editor, let name it List all assets
. In this we have couple of options:
- - this is just checking if python is supported.
- - this is mainly to create some python code in string and execute this script. We won’t use it for our script
- - this is simple node to execute python script provided in as path to script (for me it was
D:\\UE5_proj\\PythonScripts\\ListAllAssets.py
) - - this one provide more possible inputs and outputs. String can be either command like
print("It works!")
or path to script likeD:\\UE5_proj\\PythonScripts\\ListAllAssets.py
by picking rightExecutionMode
.
All inputs are: #
PythonCommand
- path or script to callExecutionMode
- how givenPythonCommand
should be interpreted possible values:ExecuteFile
- Execution file at path given inPythonCommand
(works with single commands too likeprint("Working!")
)ExecuteStatement
- Execute statement given inPythonCommand
and logs result (don’t works with path to file)EvaluateStatement
- Execute statement given inPythonCommand
and return result (don’t works with path to file)
FileExecutionScope
- how givenPythonCommand
should be interpreted possible values:Private
- Execution happens in isolated environment (all imports won’t affect other script)Public
- Execution happens in global environment (all imports will affect other public scripts)
All output are: #
Command Result
- this will return only if Command is evaluating some value that is not consumed (by printing for instance). This will be''
for commandprint("working!")
and will return'working!'
for command"working!"
. This will contain error if script fails!Log Output
- this contains array of logs that are containing log message as well as log type:Return Value
- this return true if script run successfully and false if it failed
After creating some script (any presented here) we can simply override Run function of our Blueprint and pin our function.and then in Content Browser
or Content Drawer
we can simply execute run function:
Sources #
- https://docs.unrealengine.com/5.2/en-US/scripting-the-unreal-editor-using-python/
- https://youtu.be/D-mDLwNawVU
- https://ryandowlingsoka.com/unreal/python-in-unreal/
End #
Thanks for attention, next time I will show how we can use python in more useful way and how to expose our custom C++ class to use in python.