UnrealEnginePython

repository·master·Indexed 25 days ago

https://github.com/20tab/unrealenginepython

A plugin that embeds a Python VM (3.x or 2.7) into Unreal Engine 4 (versions 4.12 through 4.23), providing access to the engine's internal API and reflection system. It enables automation, scripting, and gameplay implementation via the unreal_engine virtual module and Python-ready classes like PyActor, PyPawn, PyCharacter, and PythonComponent. The plugin supports both editor and runtime use across Windows, macOS, and Linux.

Tokens
59.5K
Snippets
161
Records
226
Agent score
83%

What's inside UnrealEnginePython

  1. Overview of UnrealEnginePython

    master

    UnrealEnginePython embeds a Python VM (supporting Python 3.x and 2.7) into both the Unreal Engine 4 editor and runtime. It provides access to the UE4 internal API and reflection system, allowing developers to automate tasks, write unit tests, implement gameplay elements, or create new plugins.

    Key features include:

    • Access to the unreal_engine virtual module (all engine features are exposed here).
    • Automatic addition of Python-ready classes: PyActor, PyPawn, PyCharacter, and PythonComponent.
    • Integration with existing Python-based pipelines (e.g., Maya, Blender).
    • Ability to change Python code even in packaged builds.
    • Access to a PythonConsole via the 'Development Menu' and an experimental 'Python Editor' via the 'Window/Layout/Python Editor' menu.

    Compatibility Note: The plugin supports Unreal Engine versions 4.12 through 4.23. For versions >= 4.25, significant refactoring is required due to changes in the UProperty subsystem (e.g., renaming UProperty to FProperty and Cast to CastField).

  2. Create a Material (Editor Only)

    master

    You can create a new base Material in the editor using the Material class or the MaterialFactoryNew factory. Using the factory is recommended for creating assets at specific paths.

    from unreal_engine.classes import MaterialFactoryNew
    import unreal_engine as ue
    
    factory = MaterialFactoryNew()
    new_material = factory.factory_create_new('/Game/Materials/NewFunnyMaterial')
    
    # To destroy the asset:
    ue.delete_asset(new_material.get_path_name())
  3. Construct a Material Graph via Python

    master

    You can programmatically build Unreal Engine materials by instantiating MaterialExpression nodes, assigning them to the material's Expressions list, and linking them using input types like ColorMaterialInput, VectorMaterialInput, or ScalarMaterialInput.

    When using ORM (Occlusion, Roughness, Metallic) textures, use ScalarMaterialInput with the Mask parameter to extract specific channels (e.g., Mask=1, MaskR=1 for Ambient Occlusion).

    Important Notes:

    • Set SamplerType for textures (e.g., EMaterialSamplerType.SAMPLERTYPE_LinearColor for ORM textures where sRGB is disabled).
    • Call material.post_edit_change() to trigger material compilation.
    • Use material.modify() to notify the editor of changes.
    # Example: Creating and linking an ORM texture node
    material_blades_orm = MaterialExpressionTextureSample('', material_blades)
    material_blades_orm.Texture = slicer_blade_texture_orm
    material_blades_orm.SamplerType = EMaterialSamplerType.SAMPLERTYPE_LinearColor
    
    # Assign nodes to the material
    material_blades.Expressions = [material_blades_base_color, material_blades_normal, material_blades_emissive, material_blades_orm]
    
    # Link nodes using specific input types
    material_blades.Roughness = ScalarMaterialInput(Expression=material_blades_orm, Mask=1, MaskG=1)
    material_blades.Metallic = ScalarMaterialInput(Expression=material_blades_orm, Mask=1, MaskB=1)
    material_blades.AmbientOcclusion = ScalarMaterialInput(Expression=material_blades_orm, Mask=1, MaskR=1)
    
    # Compile
    material_blades.post_edit_change()
  4. Use asyncio in Unreal Engine Actors

    master

    To use asyncio within an Unreal Engine Actor, you should use ue_asyncio to integrate the asyncio loop into the UE4 core. When starting a coroutine, use asyncio.ensure_future() to schedule the task. It is highly recommended to attach a callback using .add_done_callback() to handle exceptions, as unhandled exceptions in coroutines may otherwise fail silently.

    To prevent memory leaks or dangling tasks when an Actor is destroyed, you must explicitly cancel the coroutine in the end_play lifecycle method.

  5. Subclass UFactory using PyFactory

    master

    To create a custom asset importer (Factory) in Unreal Engine using Python, you must subclass PyFactory. Since the standard C++ UFactory class does not expose its methods to the reflection system, the Python plugin provides PyFactory as a bridge.

    Important Note: Only functions starting with an uppercase letter will be exposed to the Unreal Engine reflection system. Other functions will be usable only within Python.

    from unreal_engine.classes import PyFactory
    import unreal_engine as ue
    
    class ColladaFactory(PyFactory):
        def __init__(self):
            ue.log_error('Hello World, i am a useless factory')
  6. Integrate Qt (PySide2) with the Unreal Engine Loop

    master

    You can integrate Qt applications (Qt4/Qt5/PySide2) into Unreal Engine. Crucially, do not call app.exec_(), as this will hijack the engine loop. Instead, use a ticker to process Qt events within the Unreal Engine loop.

    Integration Pattern:

    1. Create a ticker function that calls app.processEvents().
    2. Register the ticker using ue.add_ticker().
    3. Attach the Qt window as a child of the editor root window using root_window.set_as_owner(widget.winId()) to ensure proper ownership on Windows.
    import sys
    import unreal_engine as ue
    import PySide2
    from PySide2 import QtWidgets
    
    app = QtWidgets.QApplication(sys.argv)
    
    def ticker_loop(delta_time):
        app.processEvents()
        return True
    
    ticker = ue.add_ticker(ticker_loop)
    
    # ... define your widget ...
    
    root_window = ue.get_editor_window()
    root_window.set_as_owner(widget.winId())
  7. Interpolate Animation Keyframes

    master

    Unreal Engine animations require a fixed number of frames, but source data often only provides sparse keyframes. To bridge this, use numpy.interp() to generate a continuous series of keyframes from non-linear data.

    Best Practice:

    • Always use Quaternions (FQuat) for interpolating rotations.
    • Do NOT use FRotator (Euler angles) for interpolation, as this leads to gimbal lock and incorrect rotation paths.