{"id":14961106,"url":"https://github.com/rmst/uniton","last_synced_at":"2025-10-13T13:32:34.139Z","repository":{"id":57477298,"uuid":"341285496","full_name":"rmst/uniton","owner":"rmst","description":"Python remote procedure call framework for the Unity game engine","archived":false,"fork":false,"pushed_at":"2021-11-08T17:15:39.000Z","size":13345,"stargazers_count":55,"open_issues_count":1,"forks_count":3,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-06-25T09:06:03.438Z","etag":null,"topics":["python","rpc-framework","unity","unity3d"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rmst.png","metadata":{"files":{"readme":"README.md","changelog":"Changelog","contributing":null,"funding":"FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":["uniton-dev"]}},"created_at":"2021-02-22T17:44:19.000Z","updated_at":"2024-10-10T04:02:31.000Z","dependencies_parsed_at":"2022-08-30T13:01:45.774Z","dependency_job_id":null,"html_url":"https://github.com/rmst/uniton","commit_stats":null,"previous_names":["rmst/pysharp"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/rmst/uniton","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmst%2Funiton","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmst%2Funiton/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmst%2Funiton/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmst%2Funiton/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rmst","download_url":"https://codeload.github.com/rmst/uniton/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmst%2Funiton/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266764910,"owners_count":23980656,"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","status":"online","status_checked_at":"2025-07-23T02:00:09.312Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["python","rpc-framework","unity","unity3d"],"created_at":"2024-09-24T13:23:50.708Z","updated_at":"2025-10-13T13:32:29.099Z","avatar_url":"https://github.com/rmst.png","language":null,"funding_links":["https://github.com/sponsors/uniton-dev"],"categories":[],"sub_categories":[],"readme":"# Uniton – Instrumentalize Unity with Python\n\nUniton lets you control the Unity game engine from Python. It aims to instrumentalize Unity and make it more useful in non-game applications.\n\n\n[comment]: \u003c\u003e (Uniton is a framework to control the Unity game engine from Python. Here is a three-minute intro video:)\n\n[comment]: \u003c\u003e ([![]\u0026#40;./res/yt_thumbnail.png\u0026#41;]\u0026#40;https://www.youtube.com/watch?v=FIpt2yv623k\u0026#41;)\n\n\u003cp float=\"left\" align=\"middle\"\u003e\n\u003cimg src=\"res/screenshot1.png\" width=49% style=\"padding: 0%;\"/\u003e\n\u003ca href=\"https://youtu.be/7BHYa1Ycb-A\"\u003e\u003cimg src=\"res/yt_thumbnail.png\" width=49% style=\"padding: 0%;\"/\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\n### Quick Start\n```bash\npip install uniton\n```\n```python\nimport uniton\n# launch an example forest scene\nue = uniton.examples.Forest()\n```\nFor more pre-built examples check [uniton/examples](https://github.com/uniton-dev/uniton/tree/main/examples)!\n\n![Examples](res/c.png)\n\n\n\n\n### Installation\nUniton requires Python 3.7+. We recommend the Anaconda/Miniconda distribution but it will work with others just as well. Install the Uniton Python package via `pip install uniton`.\n\nTo use Uniton with your own Unity project, simply drop the – [__uniton.dll__](https://github.com/uniton-dev/uniton/releases/latest/download/uniton.dll) –  into your project's `Asset` folder.\n\n### Usage\nUniton also comes with pre-built example environments that automatically download when they are first used. Below are two examples but there are more. Check out [uniton/examples](https://github.com/uniton-dev/uniton/tree/main/examples)!\n\n```python\n# The kart game from the demo video\nue = uniton.examples.KartGame()\n\n# A higher fidelity scene\nue = uniton.examples.Temple()\n```\n\n\n#### Uniton in your own Unity project\nAny Unity project can become a Uniton project simply by dropping the `uniton.dll` somewhere into the project's asset folder.\nConnect to your a running Unity app\nTo launch and connect to a Uniton app do\n```python\nimport uniton\nue = uniton.UnityEngine(path='path/to/binary')\n```\n\n```python\nue = uniton.UnityEngine()\n\n# Alternatively, to connect to a remote Uniton app do, e.g.\nue = uniton.UnityEngine(host='192.168.1.101', port=10001)\n\n# The remote Uniton app can been launched via, e.g. 'UNITONHOST=\"0.0.0.0\" UNITONPORT=10001 path/to/binary'\n# Warning: UNITONHOST=\"0.0.0.0\" should only ever be used in a private and secure network!\n# It theoretically allows everyone on the network to control the host.\n```\n\n\n#### Control time via\n```python\nue.pause()  # this can block the whole window when used in the Unity editor\nue.step()  # advances game time by ue.time.delta and renders one frame\n# more steps, etc..\nue.resume()  # resume real time operation\n```\n\n#### Access game objects via\n```python\nue.scene.\u003cGameObjectName\u003e.\u003cChildGameObjectName\u003e\n\n# Access components within game objects using lower camelcase\nue.scene.\u003cGameObjectName\u003e.\u003ccomponentName\u003e  # e.g. rigidbody, boxCollider, camera, light\n\n# Transform attributes are directly available on the game object, e.g.\nue.scene.\u003cGameObjectName\u003e.position == ue.scene.\u003cGameObjectName\u003e.transform.position\n```\n\n#### Access any C# class via\n```python\nue.\u003cnamespace\u003e.\u003cclassname\u003e\n\n# The 'UnityEngine' namespace can be omitted, i.e.\nue.\u003cclassname\u003e == ue.UnityEngine.\u003cclassname\u003e\n\n# Instantiate any C# class by calling it, as is usual in Python, e.g.\nv = ue.Vector3(0, 1, 0)\n```\n\n#### Receiving values from C#/Unity\n```python\nv.x  # returns a placeholder object for the 'x' property of a C# Vector3 object\nv.x.py # immediately returns a promise object and triggers the value of 'v.x' to be sent to Python asynchronously\nv.x.py() # blocks until the value has been received and returns the value\n\n# Currently, only a few types can be received directly, e.g. int, float, str, byte arrays.\n```\n\n#### Rendering and receiving frames\n```python\nfrom uniton import QueuedRenderer\n\nrenderer = QueuedRenderer(ue.scene.Main_Camera.Camera, width=512, height=256, render_steps=4, ipc_steps=3)\nframe = renderer.render()  # will return a Numpy array of shape (256, 512, 3) and dtype 'uint8'\n```\n\nInternally, the frame is produced as follows.\n```\nUnity GPU (render) --render_queue--\u003e Unity CPU --ipc_queue--\u003e Python\n```\n\nTherefore, `frame` actually shows the state of the game a number of `renderer.render()`-calls earlier. To be precise, that number is\n\n```python\nrenderer.delay() == render_steps + ipc_steps - 2\n```\n\nConsequently, the following will block and be slow but show the current state of the game.\n```python\nrenderer = QueuedRenderer(ue.scene.Main_Camera.Camera, width=512, height=256, render_steps=1, ipc_steps=1)\nframe = render.render()\n```\n\n### How does Uniton work?\nUniton creates placeholder objects for C# objects and functions. When a placeholder C# function is called from Python it will immediately return a new placeholder for the return value. This new placeholder object can be immediately worked with. Should the C# function throw an exception such that the actual return value never materializes, then Uniton will throw a delayed exception in Python. Attribute and method lookups on placeholder objects work the same way, as these lookups are also just functions calls internally.\n\n\n### Limitations\n- Generic C# classes and functions can't be used (please open an issue if this is important to you)\n- Python functions can't be registered as C# callbacks (please open an issue if this is important to you)\n- There is currently no documentation beyond this readme \n\n\n### Troubleshooting\nIn case that you aren't using Anaconda you might have to replace the `python` command with `python3` and the `pip` command with `python3 -m pip`. To maximize compatibilty you can install Uniton via\n```bash\npython3 -m pip install uniton --upgrade --user\n```\n\n### Uninstall\nTo remove Uniton including all example binaries that have been loaded run\n```bash\npython -m uniton delete_data\npip uninstall uniton\n```\n\n\n### Features\n[comment]: \u003c\u003e (Edit the table below via https://www.tablesgenerator.com/markdown_tables)\n\n|                                                                                      | Uniton |\n|--------------------------------------------------------------------------------------|:------:|\n| Interact live with all C# objects, functions, classes                                |    🔥   |\n| Autocomplete for all C# objects \u003csup\u003e1\u003c/sup\u003e                                         |    🔥   |\n| Fast, asynchronous execution                                                         |    🔥   |\n| Precise control over game time                                                       |    🔥   |\n| Faster-than-real-time rendering and simulation                                       |    🔥   |\n| No dependencies beyond Python and Unity                                              |    🔥   |\n| Cool [example environments](https://github.com/uniton-dev/uniton/tree/main/examples) |    🔥   |\n| Import custom C# code at runtime                                                     |    🧪   |\n| Import models at runtime \u003csup\u003e2\u003c/sup\u003e                                                |    🧪   |\n\n🔥 = available,  🧪 = work in progress\n\n\u003csup\u003e1\u003c/sup\u003e Autocomplete is available only during live-coding (e.g. python repl, ipython, jupyter notebooks). \u003cbr\u003e\n\u003csup\u003e2\u003c/sup\u003e Supports `.obj` and `.urdf` models.\n\n[comment]: \u003c\u003e (I'm also considering making an editor-focussed version of Uniton to facilitate world creation and asset management.)\n\n\n\n### License\nUniton is currently only partially open-source (https://pypi.org/project/uniton/). I probably will open-source all of it soon. In the meantime, if you need access to the source code, please contact me at simonramstedt+uniton@gmail.com\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frmst%2Funiton","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frmst%2Funiton","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frmst%2Funiton/lists"}