Python For Unity - SimplyJacoby/Unipy GitHub Wiki

Python for Unity is an experimental package that allows a user to run python scripts in Unity.

Installing Python for Unity

For 2021 Unity versions

In Window > Package Manager > Enter com.unity.scripting.python. No need to enter a version, it should install the most recent.

For older Unity versions

In Window > Package Manager > Enter https://github.com/needle-mirror/com.unity.scripting.python.git. This method is a little less desirable because you are sourcing Python for Unity from a third party git repository. I would assume updates to this repo will not be immediate.

Getting Started

Python for Unity Settings Documentation

Points of Note

  • Version 4.0.0exp5 uses Python 3.7.9
  • You can add any Python library you need to this Python installation
    • Go to Edit > Project Settings > Python for Unity > Spawn Shell in environment
    • Use pip to install any library you need
  • Compatible with requirements.txt file to ensure everyone is using the same libraries and versions

Guide

Python for Unity Guide In this repository I have created a simple Unity project that can run a Python script. You can look through that to get a feel for what you can do.

Calling the Python Script in a C# Script

  • Include these imports using UnityEditor.Scripting.Python; using UnityEditor; using UnityEngine;
  • To run a Python file:
    • PythonRunner.RunFile($"{Application.dataPath}/name_of_python_file.py");
    • You don't have to use Application.dataPath, the Python file can be stored anywhere.

Using a Python script to collect and send data

  • You can access UnityEngine in Python, simply import UnityEngine and use it how you would in C#
    • For example if you wanted to get the text of a UI Text object, you would write something like this:
      • UnityEngine.GameObject.Find("name_of_ui_text_object").GetComponent("UnityEngine.UI.Text").text
    • To set the text you would write this:
      • UnityEngine.GameObject.Find("name_of_ui_text_object").GetComponent("UnityEngine.UI.Text").text = "new text"
  • You can access variables from the calling C# script as long as they are global and public. You also have to be sure to link the C# script to a Unity GameObject so that the script is accessible as a component.
    • To get the value of a variable you would write:
      • UnityEngine.GameObject.Find("name_of_object_that_holds_script").GetComponent("name_of_c#_class").variable_name
    • To set the value of a variable you would write:
      • UnityEngine.GameObject.Find("name_of_object_that_holds_script").GetComponent("name_of_c#_class").variable_name = 6
    • This seems to work with any kind of primitive type and their wrappers, as well as arrays to some extent (see below).

Points of Note

  • You can call multiple Python scripts from a C# script.
  • There is not a way to simply pass Unity or C# data directly to a Python function. Data must be gathered by Python so I recommend creating an intermediary Python script to act as a messenger between the Python function you wish to interact with and the Unity/C# code.
  • Since Python doesn't explicitly support arrays in the same way as C# (Python has Lists), using arrays from C# isn't as straightforward as other variable types. Luckily, Python seems to be okay with indexing C# arrays, so you can access individual values. This means that we can iterate through a C# array to create a new identical Python List. The only issue is that there is no easy way to get the length of the C# array in Python, so what I did was create a global int variable in C# to store the length of the array, which I can then access in Python.
    • Setting values in a C# from Python is easy since we can index the array.
    • Adding values to a List in Python is easy, but eventually the List must be made back in to an array when it is sent to C#. After some testing, I think it would be way easier to send the Python List back to a C# ArrayList since an ArrayList is dynamically sizeable. Then you would just convert the ArrayList to an array within C#.

Limitations

  • Will only work in UnityEditor. Will not work in full builds.