{"id":13435383,"url":"https://github.com/20tab/UnrealEnginePython","last_synced_at":"2025-03-18T02:31:59.633Z","repository":{"id":37431903,"uuid":"65116537","full_name":"20tab/UnrealEnginePython","owner":"20tab","description":"Embed Python in Unreal Engine 4","archived":false,"fork":false,"pushed_at":"2022-06-22T09:35:46.000Z","size":99718,"stargazers_count":2807,"open_issues_count":367,"forks_count":756,"subscribers_count":192,"default_branch":"master","last_synced_at":"2025-03-16T14:04:31.148Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/20tab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-08-07T05:00:51.000Z","updated_at":"2025-03-15T12:32:57.000Z","dependencies_parsed_at":"2022-07-12T13:19:48.379Z","dependency_job_id":null,"html_url":"https://github.com/20tab/UnrealEnginePython","commit_stats":null,"previous_names":[],"tags_count":42,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/20tab%2FUnrealEnginePython","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/20tab%2FUnrealEnginePython/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/20tab%2FUnrealEnginePython/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/20tab%2FUnrealEnginePython/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/20tab","download_url":"https://codeload.github.com/20tab/UnrealEnginePython/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244144093,"owners_count":20405337,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T03:00:35.298Z","updated_at":"2025-03-18T02:31:59.624Z","avatar_url":"https://github.com/20tab.png","language":"C++","funding_links":[],"categories":["Scripting","C++","Assets","Game Development","[Unreal Engine](https://www.unrealengine.com/en-US/)"],"sub_categories":["Scripting","Unreal Engine: Resources"],"readme":"\n# UnrealEnginePython\nEmbed Python in Unreal Engine 4\n\nTeaser (by Kite \u0026 Lightning): https://twitter.com/KNLstudio/status/932657812466843648\n\nFixing Mixamo RootMotion tuturial: https://github.com/20tab/UnrealEnginePython/blob/master/tutorials/FixingMixamoRootMotionWithPython.md\n\nFunny snippets for working with StaticMesh and SkeletalMesh assets: https://github.com/20tab/UnrealEnginePython/blob/master/tutorials/SnippetsForStaticAndSkeletalMeshes.md\n\nMore tutorials: https://github.com/20tab/UnrealEnginePython/tree/master/tutorials\n\n# Project Status (IMPORTANT)\n\nCurrently (as april 2020) the project is on hold: between 2016 and 2018 20tab invested lot of resources in it but unfortunately epic (during 2018) decided to suddenly release its own implementation and the request made for a megagrant in 2019 by the original plugin author was rejected too.\n\nAs this plugin (still) has way more features than the Epic one and many contributors, **we are currently looking for new maintainers** helping us to keep it alive, checking PR and issues. If you are interested in working on it a few hours a week, drop us a line at info@20tab.com to discuss about it.\n\nIf you are interested in game logic scripting/modding in Unreal Engine 4 consider giving a look at the LuaMachine project (https://github.com/rdeioris/LuaMachine/).\n\nThe plugin should work up to unreal engine version 4.23 and there are forks/pull requests for 4.24. Since 4.25 Epic refactored the UProperty subsystem, so if you want to port the plugin to a version \u003e= 4.25 you should make a lot of search \u0026 replace (basically renaming UProperty to FProperty and Cast to CastField should be enough)\n\n# How and Why ?\n\nThis is a plugin embedding a whole Python VM (versions 3.x [the default and suggested one] and 2.7) In Unreal Engine 4 (both the editor and runtime).\n\nThe Python VM tries to give easy access to all of the UE4 internal api + its reflection system. This means you can use the plugin to write other plugins, to automate tasks, to write unit tests and to implement gameplay elements.\n\nIt is not meant as a way to avoid blueprints or c++ but as a good companion to them (albeit reducing the amount of c++ required for coding a game could be an interesting thing ;). If your development pipeline is already python-based (Maya, Blender, ...), this plugin could easily help you in integrating unreal into it.\n\nIf you want to have an idea of what the plugin can do, jump here: https://github.com/20tab/UnrealEnginePython/blob/master/tutorials/YourFirstAutomatedPipeline.md\n\nIn addition to this, the plugin automatically adds an actor class (PyActor), a pawn class (PyPawn), a character class (PyCharacter) and a component class (PythonComponent) for \"gentle\" integration of python in your games.\n\nIn the spirit of automating tasks, even wrappers for third party libraries used by UE4 are exposed in a 'pythonic' way. As an example the FbxSdk is exposed to allow low-level interaction with Fbx files. This is an example extracting animation curves: https://github.com/20tab/UnrealEnginePython/blob/master/examples/fbx_curves_extractor.py\n\nAnother funny feature (well, a side effect ;) is that you can change your python code even after the project has been packaged. You can potentially build a completely new game from an already packaged one.\n\nOnce the plugin is installed and enabled, you get access to the 'PythonConsole' item in the 'Development Menu', you can use it to trigger python commands directly from the editor. There is even an experimental Editor/IDE included, you can run it from the Window/Layout/Python Editor menu item.\n\nAll of the exposed engine features are under the 'unreal_engine' virtual module (it is completely coded in c into the plugin, so do not expect to run 'import unreal_engine' from a standard python shell)\n\nThe minimal supported Unreal Engine version is 4.12, while the latest is 4.23\n\nWe support official python.org releases as well as IntelPython and Anaconda distributions.\n\nNote: this plugin has nothing to do with the experimental 'PythonScriptPlugin' included in Unreal Engine \u003e= 4.19. We aim at full integration with engine and editor (included the Slate api, check here: https://github.com/20tab/UnrealEnginePython/blob/master/docs/Slate_API.md), as well as support for the vast majority of python features like asyncio, coroutines, generators, threads and third party modules.\n\n# Binary installation on Windows (64 bit)\n\nCheck in the releases page (https://github.com/20tab/UnrealEnginePython/releases) if there is a binary version that matches your configuration (otherwise open an issue asking us for it [please specify the python version too]) and download it.\n\nBinary releases are in two forms: standard and embedded. Standard uses the python installation of your system, so ensure the python installation directory is in your system PATH environment variable (otherwise you will get an error while loading your project). Embedded releases include an embedded python installation so you do not need to have python in your system.\n\nCreate (if it does not already exist) a Plugins directory in your project root directory (at the same level of Content/ and the .uproject file) and unzip the plugin into it. If your project is named FooBar you will end with FooBar/Plugins/UnrealEnginePython.\n\nOpen your project and go to the Edit/Plugins menu. Go to the bottom and under \"Project/Scripting Languages\" enable UnrealEnginePython.\n\nRestart your project and you should see the PythonConsole under the \"Window/Developer Tools\" menu\n\nBinary releases are mainly useful for editor scripting, if you want to package your project for distribution and you need the python runtime, you need a source release (see below).\n\nIf instead, you want to package your project without python, just remember to change the UnrealEnginePython.uplugin to have this line: https://github.com/20tab/UnrealEnginePython/blob/master/UnrealEnginePython.uplugin#L20 set as \"Editor\" instead of \"Runtime\"\n\n# Installation from sources on Windows (64 bit)\n\nCurrently python3.6, python3.5 and python2.7 are supported. It is highly suggested to have a python system wide installation (by default the official python distributions are installed in user's home directory) with the PATH environment variable including it (if you change the PATH variable remember to reboot the system before running the build procedure, this is not strictly required but will ensure the PATH is updated). If the PATH variable does not contain the path of your python installation you will see a warning in the build log/output.\n\nDownload a source official release or simply clone the repository for latest updates:\n\n```sh\ngit clone https://github.com/20tab/UnrealEnginePython\n```\n\nBy default the build procedure will try to discover your python installation looking at hardcoded known paths. If you want to specify a custom python installation (or the autodetection simply fails) you can change it in the Source/UnrealEnginePython/UnrealEnginePython.Build.cs file at this line: https://github.com/20tab/UnrealEnginePython/blob/master/Source/UnrealEnginePython/UnrealEnginePython.Build.cs#L10\n\nNote: ensure you have a 64bit python installation\n\n\nchoose a project you want to install the plugin into, open the file explorer (you can do it from the epic launcher too) and:\n\n* create a Plugins/ directory (if it does not exist) in your project and copy the directory UnrealEnginePython into it\n* from the file explorer right click on the project main file and choose 'generate visual studio project files'\n* open visual studio, you should now see Plugins/UnrealEnginePython in your solution explorer\n* run the compilation from visual studio\n* once the compilation ends, double check the python libraries can be found by the plugin (they must be in the system PATH like previously described, or brutally copy them in the Binaries/Win64 directory of the just built plugin)\n* now you can re-run the unreal engine editor\n\nIf all goes well, you will see 'Python Console' in the \"Window/Developer Tools\" menu\n\nIf you want to package your project (it is required only if you need to have a python VM at runtime, read: your game logic is programmed in python) ensure the Content/Scripts/ue_site.py file is in your project (it can be empty). At the end of the build procedure ensure to copy all of your required python scripts in the final directory. Remember that unless you add an embedded python in your final build, the final users of your project will require python installed in his/her system.\n\nIf you want to package without python, just remember to change the UnrealEnginePython.uplugin to have this line: https://github.com/20tab/UnrealEnginePython/blob/master/UnrealEnginePython.uplugin#L20 set as \"Editor\" instead of \"Runtime\"\n\n# Binaries installation on MaxOSX\n\nCheck in the releases page (https://github.com/20tab/UnrealEnginePython/releases) if there is a binary version that matches your configuration (otherwise open an issue asking us for it [please specify the python version too]) and download it.\n\nBinary releases for MacOSX expects an official python installation (the packages you get from python.org).\n\nCreate (if it does not already exist) a Plugins directory in your project root directory (at the same level of Content/ and the .uproject file) and unzip the plugin into it. If your project is named FooBar you will end with FooBar/Plugins/UnrealEnginePython.\n\nOpen your project and go to the Edit/Plugins menu. Go to the bottom and under \"Project/Scripting Languages\" enable UnrealEnginePython.\n\nRestart your project and you should see the PythonConsole under the \"Window/Developer Tools\" menu\n\nBinary releases are mainly useful for editor scripting, if you want to package your project for distribution and you need the python runtime, you need a source release (see below).\n\nIf instead, you want to package your project without python, just remember to change the UnrealEnginePython.uplugin to have this line: https://github.com/20tab/UnrealEnginePython/blob/master/UnrealEnginePython.uplugin#L20 set as \"Editor\" instead of \"Runtime\"\n\n# Installation from sources on MacOSX\n\n* install the latest official python distribution from python.org (the installation will end in the \"/Library/Frameworks/Python.framework/Versions/X.Y\" directory).\n* create a new unreal engine blank c++ project (NOT a blueprint one, otherwise XCode will not be initialized)\n* create a Plugins directory in the project directory\n* move to the Plugins directory and clone the plugin repository\n\n\n```sh\ngit clone https://github.com/20tab/UnrealEnginePython\n```\n\n* restart the editor and a popup should appear asking your for confirmation of the build of the plugin.\n* Once the plugin is built, go to the output log console and filter for 'Python'. You should see the Python VM banner.\n\nThe build procedure will try to automatically discover python installations. If you need custom paths, just edit here:\n\nhttps://github.com/20tab/UnrealEnginePython/blob/master/Source/UnrealEnginePython/UnrealEnginePython.Build.cs#L10\n\nUpgrading on MacOSX\n-------------------\n\nTo upgrade to the latest development version of UnrealEnginePython:\n* move to the Plugins directory in the project directory and use git pull\n\n```sh\ngit pull\n```\n\n* move to UnrealEnginePython/Binaries/Mac from the Plugin directory\n* remove the plugin libraries to warn UnrealEngine to recompile the plugin\n\n```sh\nrm *.dylib\n```\n\n* restart the editor and a popup should appear asking your for confirmation of the build of the plugin.\n* Once the plugin is built, go to the output log console and filter for 'Python'. You should see the Python VM banner.\n\nInstallation from sources On Linux (64 bit)\n-------------------------------------------\n\nCurrently the suggested distribution is Ubuntu Xenial (LTS 16.04) 64bit. Obviously you need to already have an Unreal Engine build (note that on ubuntu xenial you need to install the clang-3.5 package to build the editor). Both python2.7 and python3.5 are supported and the default configuration assumes python3 (so ensure to install the python3-dev package).\n\n* Create a new C++ project and close the editor once the project is fully started\n* go to the just created project directory and create the Plugins folder\n* move to the Plugins folder and clone the plugin repository:\n\n\n```sh\ngit clone https://github.com/20tab/UnrealEnginePython\n```\n\n* re-open your project, this time you will get a popup asking you for re-building the python plugin. Choose yes and wait.\n\nNOTE: always run your project from a terminal so you can see startup logs (they are really useful when building the plugin the first time, if you cannot build the plugin, open an issue on github pasting the related log lines).\n\nIf you want to use python2 (or another specific version) just edit the Source/UnrealEnginePython/UnrealEnginePython.Build.cs file and change the pythonHome string accordingly (ensure to have the python2.7-dev package installed).\n\n\nUpgrade the plugin on Linux\n---------------------------\n\nJust remove the .so files in Plugins/UnrealEnginePython/Binaries/Linux and pull the latest code.\n\nAt the next run the build procedure wil be started again.\n\nAndroid Deployment\n------------------\n\nCheck https://github.com/20tab/UnrealEnginePython/blob/master/docs/Android.md\n\n# Installation on other platforms\n\nCurrently only Windows, MacOSX, Linux and Android are supported.\n\n# Using Python with Unreal Engine (finally)\n\nIf your objective is to script the editor, you can directly jump to\n\nhttps://github.com/20tab/UnrealEnginePython/tree/master/docs\n\nand\n\nhttps://github.com/20tab/UnrealEnginePython/tree/master/examples\n\nThe first directory contains the official documentation for specific areas, while the second one is a collection of python scripts doing any sort of 'magic' with your project ;)\n\nCreating a new blueprint class managed by python\n------------------------------------------------\n\nWe are going to create a new Actor based on python (instead of C++ or blueprints)\n\nThis is the \"gentle\" approach, using a 'proxy' python class to speak with the UE4 api. Once you get familiar with the system, you can\ngo further and start working withe native subclassing api (https://github.com/20tab/UnrealEnginePython/blob/master/docs/Subclassing_API.md) \n\nIn the content browser click on 'add new' and choose 'blueprint class'\n\nIn the classes menu choose 'PyActor':\n\n![Alt text](screenshots/unreal_screenshot1.png?raw=true \"Screenshot 1\")\n\nYou now have a new asset, give it a meaningful name, and double click on it to start configuring it in the blueprint editor\n\n![Alt text](screenshots/unreal_screenshot2.png?raw=true \"Screenshot 2\")\n\nOn the right (in the 'Details' tab) you will find the Python section.\n\nFor now only 'Python Module' and 'Python Class' are meaningful.\n\nGo to the Content directory of your project and create a directory named 'Scripts'. This is where all of your python modules will reside. With your favourite text editor create a new python module (like funnygameclasses.py), and define a new class into it:\n\n```py\nimport unreal_engine as ue\n\nue.log('Hello i am a Python module')\n\nclass Hero:\n\n    # this is called on game start\n    def begin_play(self):\n        ue.log('Begin Play on Hero class')\n        \n    # this is called at every 'tick'    \n    def tick(self, delta_time):\n        # get current location\n        location = self.uobject.get_actor_location()\n        # increase Z honouring delta_time\n        location.z += 100 * delta_time\n        # set new location\n        self.uobject.set_actor_location(location)\n\n```\n\nNow, go back to the blueprint editor and set 'funnygameclasses' in the 'Python Module' field, and 'Hero' in 'Python Class'\n\nAs you can see the actor will simply move over the z axis, but we need to give it some kind of visual representation to have a feedback in the scene. In the blueprint editor click on 'add component' and add some shape (a sphere, or a cube, or whatever you want). Save and Compile your blueprint.\n\nNow you can drag the bluprint from the content browser to the scene and just click 'Play'.\n\nYou should see your actor moving along the 'z' axis at a speed of 1 meter per second\n\nBy default a 'begin_play' and a 'tick' method are expected (they will be automatically taken into account if found). In addition to them an 'automagic' system for defining event is available:\n\n```py\ndef on_actor_begin_overlap(self, me, other_actor):\n    pass\n\ndef on_actor_end_overlap(self, me, other_actor):\n    pass\n    \ndef on_actor_hit(self, me, other_actor, normal_impulse, hit_result):\n    pass\n\n...\n```\n\nBasically for each method startwing with 'on_' the related delegate/event is automatically configured (if available).\n\nIf you instead prefer to manually setup events, the following functions are exposed:\n\n```py\n\nclass Ball:\n\n    def begin_play(self):\n        self.uobject.bind_event('OnActorBeginOverlap', self.manage_overlap)\n        self.uobject.bind_action('Jump', ue.IE_PRESSED, self.uobject.jump)\n        self.uobject.bind_key('K', ue.IE_PRESSED, self.you_pressed_K)\n        self.uobject.bind_axis('MoveForward', self.move_forward)\n        \n    def manage_overlap(self, me, other):\n        ue.print_string('overlapping ' + other.get_name())\n        \n    def you_pressed_K(self):\n        ue.log_warning('you pressed K')\n        \n     def move_forward(self, amount):\n        ue.print_string('axis value: ' + str(amount))\n        \n\n```\n\n\nWhat is 'self.uobject' ?\n------------------------\n\nTo allow seamless Python integration, each UObject of the engine is automatically mapped to a special Python Object (ue_PyUObject).\n\nWhenever you want to access a UObject from python, you effectively get a reference to a ue_PyUObject exposing (via its methods) the features of the UObject (properties, functions, ....)\n\nThis special python object is cached into a c++ map in memory. (The key is the UObject pointer, the value is the ue_PyUObject pointer)\n\nTo be more clear, a call to:\n\n```py\ntext_render_component = unreal_engine.find_class('TextRenderComponent')\n```\n\nwill internally search for the 'TextRenderComponent' class (via unreal c++ reflection) and when found will check if it is available in the cache, otherwise it will create a new ue_PyUObject object that will be placed in the cache.\n\nFrom the previous example the 'text_render_component' maintains a mapping to the UObject (well a UClass in this example).\n\nPay attention: the python class you map to the PyActor (or PyPawn, PyCharacter or PyComponent), is not a ue_PyUObject. It is a classic python class that holds a reference (via the 'uobject' field) to the related ue_PyUObject mapped object. The best technical term to describe those classes is 'proxy'.\n\nNote about 'uobject' from now on\n---------------------------------\n\nIn the following lines, whenever you find a reference to 'uobject' it is meant as a ue_PyUObject object.\n\nAdding a python component to an Actor\n-------------------------------------\n\nThis works in the same way as the PyActor class, but it is, well, a component. You can attach it (search for the 'Python' component) to any actor.\n\nRemember that for components, the self.uobject field point to the component itself, not the actor.\n\nTo access the actor you can use:\n\n```py\nactor = self.uobject.get_owner()\n```\n\nThe following example implements the third person official blueprint as a python component:\n\n```py\nclass Player:\n    \n    def begin_play(self):\n        # get a reference to the owing pawn (a character)\n        self.pawn = self.uobject.get_owner()\n\n        # the following two values were originally implemented as blueprint variable\n        self.base_turn_rate = 45.0\n        self.base_look_up_rate = 45.0\n\n        # bind axis events\n        self.pawn.bind_axis('TurnRate', self.turn)\n        self.pawn.bind_axis('LookUpRate', self.look_up)\n        self.pawn.bind_axis('Turn', self.pawn.add_controller_yaw_input)\n        self.pawn.bind_axis('LookUp', self.pawn.add_controller_pitch_input)\n\n        self.pawn.bind_axis('MoveForward', self.move_forward)\n        self.pawn.bind_axis('MoveRight', self.move_right)\n\n        # bind actions\n        self.pawn.bind_action('Jump', ue.IE_PRESSED, self.pawn.jump)\n        self.pawn.bind_action('Jump', ue.IE_RELEASED, self.pawn.stop_jumping)\n\n    def turn(self, axis_value):\n        turn_rate = axis_value * self.base_turn_rate * self.uobject.get_world_delta_seconds()\n        self.pawn.add_controller_yaw_input(turn_rate)\n\n    def look_up(self, axis_value):\n        look_up_rate = axis_value * self.base_look_up_rate * self.uobject.get_world_delta_seconds()\n        self.pawn.add_controller_pitch_input(look_up_rate)\n\n    def move_forward(self, axis_value):\n        rot = self.pawn.get_control_rotation()\n        fwd = ue.get_forward_vector(0, 0, rot[2])\n        self.pawn.add_movement_input(fwd, axis_value)\n\n    def move_right(self, axis_value):\n        rot = self.pawn.get_control_rotation()\n        right = ue.get_right_vector(0, 0, rot[2])\n        self.pawn.add_movement_input(right, axis_value)\n```\n\nNative methods VS reflection\n----------------------------\n\nBy default the UObject class defines __getattr__ and __setattr__ as wrappers for unreal properties and functions.\n\nThis means that calling:\n\n```py\nself.uobject.bCanBeDamaged = True\n```\n\nit is the same as\n\n```py\nself.uobject.set_property('bCanBeDamaged', True)\n```\n\nAs well as function calls:\n\n```py\nvec = self.uobject.GetActorRightForward()\n```\n\nmeans\n\n```py\nvec = self.uobject.call_function('GetActorRightForward')\n```\n\nAnd more important (and handy) K2_ functions are automagically exposed too:\n\n```py\nvec = self.uobject.GetActorLocation()\n```\n\nis equal to:\n\n```py\nvec = self.uobject.call_function('K2_GetActorLocation')\n```\n\nObviously you can combine methods/properties:\n\n```py\nself.uobject.CharacterMovement.MaxWalkSpeed = 600.0\n```\n\nAlbeit the system allows for full unreal api usage, reflection is slower than native methods.\n\nTry to use native methods whenever possible, and open pull request whenever you think a function should be exposed as native methods.\n\nSo\n\n```py\nvec = self.uobject.get_actor_location()\n```\n\nis way faster than\n\n```py\nvec = self.uobject.GetActorLocation()\n```\n\nReflection based functions are those in camelcase (or with the first capital letter). Native functions instead follow the python style, with lower case, underscore-as-separator function names.\n\nNote that, in editor builds, when you change the property of an archetype (included ClassDefaultObject) via __setattr__ all of the archtype instances will be updated too.\n\nTo be more clear:\n\n```python\nyour_blueprint.GeneratedClass.get_cdo().CharacterMovement.MaxWalkSpeed = 600.0\n```\n\nis a super shortcut for:\n\n```python\nyour_blueprint.GeneratedClass.get_cdo().CharacterMovement.pre_edit_change('MaxWalkSpeed')\nyour_blueprint.GeneratedClass.get_cdo().CharacterMovement.set_property('MaxWalkSpeed', 600.0)\nyour_blueprint.GeneratedClass.get_cdo().CharacterMovement.post_edit_change_property('MaxWalkSpeed')\nfor instance in your_blueprint.GeneratedClass.get_cdo().CharacterMovement.get_archetype_instances():\n    instance.pre_edit_change('MaxWalkSpeed')\n    instance.set_property('MaxWalkSpeed', 600.0)\n    instance.post_edit_change_property('MaxWalkSpeed')\n```\n\n\nThe automagic UClass, UStruct and UEnums mappers\n------------------------------------------------\n\nInstead of doing a gazilion of unreal_engine.find_class(name) calls, the plugin adds three 'magic' modules called unreal_engine.classes, unreal_engine.structs and unreal_engine.enums. They allows to import unreal classes/structs/enums like python classes:\n\n```py\nfrom unreal_engine.classes import ActorComponent, ForceFeedbackEffect, KismetSystemLibrary\n\n...\ncomponents = self.uobject.get_owner().GetComponentsByClass(ActorComponent)\n\n...\nself.force_feedback = ue.load_object(ForceFeedbackEffect, '/Game/vibrate')\nself.uobject.get_player_controller().ClientPlayForceFeedback(self.force_feedback)\n\n...\nname = KismetSystemLibrary.GetObjectName(self.actor)\n```\n\nthe last example, shows another magic feature: static classes function calls. Obviously in this specific case using self.actor.get_name() would have been the best approach, but this feature allows you to access your blueprint function libraries too.\n\nAnother example for adding a widget:\n\n```py\nfrom unreal_engine.classes import WidgetBlueprintLibrary\n\nclass PythonFunnyActor:\n    def begin_play(self):\n        WidgetBlueprintLibrary.Create(self.uobject, ue.find_class('velocity_C'))\n```\n\nAnd another complex example using enums, keyword arguments and output values (output values are appended after the return value):\n\n```py\n\nimport unreal_engine as ue\nfrom unreal_engine import FVector, FRotator, FTransform, FHitResult\nfrom unreal_engine.classes import ActorComponent, ForceFeedbackEffect, KismetSystemLibrary, WidgetBlueprintLibrary\nfrom unreal_engine.enums import EInputEvent, ETraceTypeQuery, EDrawDebugTrace\n\n...\n\nis_hitting_something, hit_result = KismetSystemLibrary.LineTraceSingle_NEW(self.actor, self.actor.get_actor_location(), FVector(300, 300, 300), ETraceTypeQuery.TraceTypeQuery1, DrawDebugType=EDrawDebugTrace.ForOneFrame)\nif is_hitting_something:\n    ue.log(hit_result)\n```\n\nTo create a new struct instance you can do:\n\n```python\nfrom unreal_engine.structs import TerrificStruct\n\nts = TerrificStruct()\n```\n\nor (to initialize some of its fields)\n\n```python\nfrom unreal_engine.structs import TerrificStruct\n\nts = TerrificStruct(Foo='Bar', Test=17.22)\n```\n\nTo access the fields of a struct just call the fields() method.\n\nA good example of struct usage is available here: https://github.com/20tab/UnrealEnginePython/blob/master/docs/Settings.md\n\n\nMore details here: https://github.com/20tab/UnrealEnginePython/blob/master/docs/MemoryManagement.md\n\nThe ue_site.py file\n-------------------\n\nOn Editor/Engine start, the ue_site module is tried for import. You should place initialization code there. If the module cannot be imported, you will get a (harmful) message in the logs.\n\nPyPawn\n------\n\nThis works like PyActor, but this time you generate a new Pawn class (that you can posses with a controller)\n\n\nThe 'World' concept\n-------------------\n\nEvery actor is mapped to a world (UWorld in c++). Generally when you play on a Level your objects all live in the same world, but at the same time there could be multiple worlds (for example while testing in the editor there is a world for the editor and one for the simulation)\n\nWhile it is pretty rare to reference other worlds, you may need to compare the world of two uobject's (for example you may have a reference in your python module to a uobject of a hidden world and you want to check if you need to use it).\n\nThe uobject.get_world() function returns a uobject representing the world (the C++ UWorld class)\n\nThe uobject api\n---------------\n\nEach uobject represent a UObject class of the Engine. This C++ class is basically the root of all the other classes (Actors, Pawns, components, properties ...). Thanks to Unreal Engine reflection system we do not need to implement a python class for each unreal engine class, but for performance reason we expose the most common methods. The uobject system checks for the type of the mapped C++ UObject and will call the method only if it is safe to call it.\n\nSometime methods are implemented for automatically getting the right object. As an example get_actor_location() when called over a component will automatically retrieve the related actor and will call C++ AActor::GetActorLocation() method over it.\n\nWhen this automagic approach is too risky, the method will check for the uobject type and will raise an exception in the case of inconsistencies.\n\nRemember, there is no need to implement every single engine class method, the reflection system is powerful enough to be governed only via properties and function calls (check the uobject call() method)\n\nMost-used methods are implemented directly as uobject methods for performance reasons.\n\nYou can get the the list of uobject api methods here: https://github.com/20tab/UnrealEnginePython/blob/master/docs/uobject_API.md\n\nAutomatic module reloading (Editor only)\n----------------------------------------\n\nWhen in the editor, you can change the code of your modules mapped to proxies without restarting the project. The editor will reload the module every time a PyActor, PyPawn or PythonComponent is instantiated. This is obviously not the best approach. In the future we would like to implement timestamp monitoring on the file to reload only when needed.\n\nPrimitives and Math functions\n-----------------------------\n\nThe plugin exposes FVector, FRotator, FQuat, FColor, FHitResult and a bunch of the internal handles.\n\nWhere meaningful, math operations are exposed:\n\n\n```py\nimport unreal_engine\n\nclass ActorGoingUp:\n    def begin_play(self):\n        # 1 meter by second\n        self.speed = 100\n    \n    def tick(self, delta_time):\n        # get the up vector\n        up = self.uobject.get_up_vector()\n        # get current position\n        position = self.uobject.get_actor_location()\n        # build a direction vector based on speed\n        up_amount = up * self.speed * delta_time)\n        # sum the direction to the position\n        position += up_amount\n        # set the new position\n        self.uobject.set_actor_location(new_position)\n```\n\nReferencing objects\n-------------------\n\nYou can use find_class(), find_struct() and find_object() functions to reference already loaded classes/objects.\n\nIf you need to reference assets (still) not loaded in the engine you can use load_struct(), load_class() or load_object():\n\n```py\na_struct_data = ue.load_struct('/Game/Data')\nue.log(a_struct_data.as_dict())\n```\n\nor to find a specific asset:\n\n```py\ntexture_class = ue.find_class('Texture2D')\na_specific_texture = ue.load_object(texture_class, '/Game/Textures/logo2')\n```\n\nMore infos about dealing with assets are available here: https://github.com/20tab/UnrealEnginePython/blob/master/docs/ManagingAssets.md\n\nThe as_dict() method\n--------------------\n\nThis special method can be called on any uobject: it will attempt to serialize it to a python dictionary\n\n\n\nBlueprints integration\n----------------------\n\nYou can call blueprints functions (or custom events) via the .call() and .call_function() methods:\n\n```py\nyour_funny_blueprint_object.call('AFunctionOrACustomEvent with_a_arg')\n```\n\nWhenever you need to reference external object, avoid using find_object() and similar. Instead add a public variable in your blueprint\npointing to the specific object. You can then reference this object easily getting the property value:\n\n```py\nthe_other_object = self.uobject.get_property('target')\nthe_other_object.set_actor_location(0, 0, 0)\n```\n\n.call_function() is more advanced, as it allows for return values and python args:\n\n```py\n# an example of moving an object z with curves:\nclass Curver:\n    def begin_play(self):\n        self.curve = self.uobject.get_owner().get_property('curve')\n        self.accumulator = 0.0\n    def tick(self, delta_time):\n        location = self.uobject.get_actor_location()\n        z = self.curve.call_function('GetFloatValue', self.accumulator) * 100\n        self.uobject.set_actor_location(location.x, location.y, z)\n        self.accumulator += delta_time\n\n```\n\nEvents\n------\n\nYou can easily bind events (as seen before) with the bind_event function\n\n```py\nself.uobject.bind_event('OnActorBeginOverlap', a_funny_callback)\n```\n\nYou can obviously bind to Event Dispatchers too.\n\nTriggering events is basically like calling functions, self.uobject.call('OnActorBeginOverlap') will be more than enough.\n\nIf you want to map events from a blueprint to a python function, the best thing to do is using the 'python call' blueprint functions exposed by the various plugin classes:\n\n![Alt text](screenshots/unreal_screenshot3.png?raw=true \"Screenshot 3\")\n\nPlugin Configuration\n--------------------\n\nYou can tune your python environment adding a [Python] stanza to the Config/DefaultEngine.ini file.\n\nThe following parameters are supported:\n\n* `Home`: set the path of the python installation, useful for forcing the python vm to search modules in a specific directory (like old-style virtualenvs)\n* `RelativeHome`: like Home but relative to the /Content directory\n* `ProgramName`: set the python program name path\n* `RelativeProgramName`: like ProgramName, but the path is relative to the /Content directory\n* `ScriptsPath`: change the default path on where Unreal Engine searches for python scripts\n* `RelativeScriptsPath`: like ScriptsPath, but relative to the /Content directory\n* `AdditionalModulesPath`: add the specified directory to sys.path\n* `RelativeAdditionalModulesPath`: like AdditionalModulesPath, but the path is relative to the /Content directory\n* `ZipPath`: allow to specify a .zip file that is added to sys.path\n* `RelativeZipPath`: like ZipPath, but the path is relative to the /Content directory\n* `ImportModules: comma/space/semicolon separated list of modules to import on startup (after ue_site)\n\nExample:\n\n```ini\n[Python]\nHome = C:/FooBar/Python36\n```\n\nPackaging\n---------\n\nWhen you package your projects, remember to include the libpython (dll or dylib or .so based on your operating system) in the binaries folder and the Scripts directory (if you do not want to force the user to have python installed in its system). For Windows system you can use the embedded distributions available in the official python.org site. Just uncompress the zip in the plugin binary folder (at the same level of UnrealEnginePython.dll)\n\nIf you do not want to distribute python sources, you can include only the ```__pycache__``` directory with the bytecode.\n\nDo not forget to include python third party modules (if you use any of them in your project)\n\nQuick Examples\n--------------\n\nThis is a PyActor destroying itself whenever another actor overlap it. Remember to add a mesh component to it (like a sphere) and set its collision behaviour as 'OverlapAll'. This could be tested with the third person official template.\n\n```py\nclass Ball:\n    def begin_play(self):\n        ue.print_string('Hello')\n\n    def on_actor_begin_overlap(self, other_actor):\n        ue.print_string('Collided with ' + other_actor.get_name())\n        self.uobject.actor_destroy()\n```\n\nNow we create (at runtime !!!) a whole new PyActor:\n\n```python\nclass SuperHero:\n    def begin_play(self):\n        # spawn a new PyActor\n        new_actor = self.uobject.actor_spawn(ue.find_class('PyActor'), Fvector(0, 0, 0),FRotator(0, 0, 90))\n        # add a sphere component as the root one\n        static_mesh = new_actor.add_actor_root_component(ue.find_class('StaticMeshComponent'), 'SphereMesh')\n        # set the mesh as the Sphere asset\n        static_mesh.call('SetStaticMesh /Engine/EngineMeshes/Sphere.Sphere')\n        # set the python module\n        new_actor.set_property('PythonModule', 'gameclasses')\n        # set the python class\n        new_actor.set_property('PythonClass', 'Vertical')\n```\n\nFor more examples: https://github.com/20tab/UnrealEnginePython/tree/master/examples\n\nSpawning Notes\n--------------\n\nRemember that only Actors can be spawned in a world, and that even the editor is a valid world:\n\n```python\nimport unreal_engine as ue\nfrom unreal_engine.classes import Actor, Character\nfrom unreal_engine import FVector, FRotator\n\nworld = ue.get_editor_world()\nactor000 = world.actor_spawn(Actor, FVector(0, 0, 0), FRotator(0, 0, 0))\ncharacter000 = world.actor_spawn(Character, FVector(100, 100, 100), FRotator(0, 0, 0))\n```\n\nRemember that the Blueprint asset is not a valid actor by itself, you need to get the class generated by the blueprint:\n\n```python\nimport unreal_engine as ue\nfrom unreal_engine.classes import Blueprint\nfrom unreal_engine import FVector, FRotator\n\nworld = ue.get_editor_world()\n\nblueprint = ue.load_object(Blueprint, '/Game/TestBall.TestBall')\nactor000 = world.actor_spawn(blueprint.GeneratedClass, FVector(0, 0, 0), FRotator(0, 0, 0))\n```\n\notherwise you can directly reference the BlueprintGeneratedClass\n\n```python\nimport unreal_engine as ue\nfrom unreal_engine.classes import BlueprintGeneratedClass\nfrom unreal_engine import FVector, FRotator\n\nworld = ue.get_editor_world()\n\nblueprint_actor = ue.load_object(BlueprintGeneratedClass, '/Game/TestBall.TestBall_C')\nactor000 = world.actor_spawn(blueprint_actor, FVector(0, 0, 0), FRotator(0, 0, 0))\n```\n\nThe Python Editor\n-----------------\n\nStarting from version 20170301 a handy editor has been added to the plugin:\n\n![Alt text](screenshots/python_editor_screenshot001.png?raw=true \"Python Editor Screenshot\")\n\nIt allows you to run, create, modify and delete scripts directly from the UE editor\n\nThe first pull request for the editor has been issued by https://github.com/sun5471 so many thanks to him ;)\n\nIntegration with Qt4/Qt5/PySide2\n--------------------------------\n\nThanks to solid GIL management, you can integrate Qt python apps in Unreal Engine 4.\n\nPay attention to not call app.exec_() as it will result in Qt taking control of the UE loop. Instead use a ticker to integrate the Qt loop in the editor loop:\n\n```python\n\n# save it as ueqt.py\nimport sys\nimport unreal_engine as ue\nimport PySide2\nfrom PySide2 import QtWidgets\n\napp = QtWidgets.QApplication(sys.argv)\n\ndef ticker_loop(delta_time):\n    app.processEvents()\n    return True\n\nticker = ue.add_ticker(ticker_loop)\n```\nnow you can start writing your gui (this is a simple example loading asset thumbnail):\n\n```python\nimport ueqt\nfrom PySide2 import QtCore, QtWidgets, QtGui\nimport unreal_engine as ue\n\nfrom unreal_engine import FARFilter\n\n_filter = FARFilter()\n_filter.class_names = ['SkeletalMesh', 'Material']\n\nclass MyWidget(QtWidgets.QWidget):\n    def __init__(self):\n        super().__init__()\n        self.vertical = QtWidgets.QVBoxLayout()\n        self.scroll = QtWidgets.QScrollArea()\n        self.content = QtWidgets.QWidget()\n        self.scroll.setWidget(self.content)\n        self.scroll.setWidgetResizable(True)\n        self.layout = QtWidgets.QVBoxLayout()\n\t\n        for asset_data in ue.get_assets_by_filter(_filter, True):\n            try:\n                thumbnail = asset_data.get_thumbnail()\n            except:\n                continue\n\n            label = QtWidgets.QLabel()\n            data = thumbnail.get_uncompressed_image_data()\n            image = QtGui.QImage(data, 256, 256, QtGui.QImage.Format_RGB32)\n            label.setPixmap(QtGui.QPixmap.fromImage(image).scaled(256, 256))\n            self.layout.addWidget(label)\n\n        self.content.setLayout(self.layout)\n        self.vertical.addWidget(self.scroll)\n        self.setLayout(self.vertical)\n\n\n\nwidget = MyWidget()\nwidget.resize(800, 600)\nwidget.show()\n\nroot_window = ue.get_editor_window()\nroot_window.set_as_owner(widget.winId())\n```\n\n(no need to allocate a new Qt app, or start it, as the UE4 Editor, thanks to to ueqt module is now the Qt app itself)\n\nNote the 2 final lines: they 'attach' the Qt window as a 'child' of the editor root window. Note that on windows platform this is not simple parenting but 'ownership'.\n\nMemory management\n-----------------\n\nDealing with 2 different GC's is really challenging.\n\nStarting from release 20180226 a new memory management system has been added (FUnrealEnginePythonHouseKeeper, available here https://github.com/20tab/UnrealEnginePython/blob/master/Source/UnrealEnginePython/Public/PythonHouseKeeper.h). This new system is completely integrated with the Unreal Engine reflection-based GC and will hold track of each ue_PyUObject abd the related UObject to understand when a python object can be safely destroyed.\n\nThe same system works for delegates, as well as Slate.\n\nMore details here: https://github.com/20tab/UnrealEnginePython/blob/master/docs/MemoryManagement.md\n\nUnit Testing\n------------\n\nThe repository includes the tests/ directory from which unit tests will be run.\n\nTo run the unit tests (ensure to run them on an empty/useless project to avoid messing with assets) run the following commands from the ue4 python console:\n\n```python\nimport unreal_engine as ue\nue.py_exec(ue.find_plugin('UnrealEnginePython').get_base_dir() + '/run_tests.py')\n```\nif you plan to add new features to the plugin, including a test suite in your pull request will be really appreciated ;)\n\nThreading\n------------------------\n\nSince release 20180624 threading is fully supported.\n\nAs with native threads, do not modify (included deletion) UObjects from non-main threads.\n\nAccessing Python Proxy From UObject\n-----------------------------------\n\nSometimes you may have a UObject and know that it is backed by a python object. To get the python object from the UObject, use the `get_py_proxy` method. For example, imagine you have the following situation:\n\n   1. There is a `PyActor` sub-class called `PyExplosiveActor` which has `Explosive` as its python class.\n   2. The `Explosive` has a `go_boom` python method.\n   3. There is a `PyActor` sub-class called `PyBadGuyActor` which has a Blueprint property called `MyBomb` and a python class called `BadGuy`.\n   4. The `BadGuy` instance in python knows that its UObject has its `MyBomb` as an instance of `PyExplosiveActor` and wants to call the `go_boom` python method.\n   \nThis would be resolved as shown below:\n\n```python\nimport unreal_engine as ue\n\nclass Explosive:\n    'Python representation for PyExplosiveActor in UE4'\n\n    def go_boom(self):\n        # do python stuff to explode\n        ...\n        self.uobject.destory()\n\nclass BadGuy:\n    'Python reprsentation for PyBadGuyActor in UE4'\n   \n    def ignite_bomb(self, delay):\n        bomb = self.uobject.MyBomb\n        py_bomb = bomb.get_py_proxy()\n        py_bomb.go_boom()\n\t\n```\n\nWhat is going on here in `BadGuy` is that self.uobject is a reference to the PyActor UObject and `self.uobject.MyBomb` is a reference to the `PyExplosive` uobject. But instead you want to access its proxy class (`Explosive`). The `get_py_proxy()` method returns the python custom class, `Explosive` that the `PyExplosiveActor` object is mapped to.\n\nStatus and Known issues\n-----------------------\n\nExposing the full ue4 api is a huge amount of work, feel free to make pull requests for your specific needs.\n\nWe still do not have a plugin icon ;)\n\nWe try to do our best to \"protect\" the user, but you can effectively crash UE from python as you are effectively calling the C/C++ api\n\nContacts and Commercial Support\n-------------------------------\n\nIf you need commercial support for UnrealEnginePython just drop a mail to info at 20tab.com\n\nFollow @unbit on twitter for news about the project\n\nSpecial Thanks\n--------------\n\nSuch a big project requires constant sponsorship, special thanks go to:\n\n* Kite \u0026 Lighting http://kiteandlightning.la/ (they are sponsoring various areas of the project, expecially the slate api)\n\n* GoodTH.INC https://www.goodthinc.com/ (they are sponsoring the sequencer api)\n\n* Quixel AB https://megascans.se/ (built their integration tool over UnrealEnginePython giving us tons of useful feedbacks and ideas)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F20tab%2FUnrealEnginePython","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F20tab%2FUnrealEnginePython","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F20tab%2FUnrealEnginePython/lists"}