Skip to content

Python.NET

Jacob edited this page May 28, 2021 · 30 revisions

Python.NET

Installation

Installing NuGet Package Manager

  • Download the latest NuGetForUnity .unitypackage here
  • In Unity, go to Assets > Import Package > Custom Package, locate where you downloaded NuGetForUnity, and install it.
  • You should now see NuGet in the Unity menu bar.

Installing Python.NET

  • In Unity, go to NuGet > Manage NuGet Packages, select Show All Versions and Show Prerelease.
  • Search for pythonnet.
  • Install pythonnet Version 3.0.0-preview2021-05-03.

Installing Embedded Python

  • Download a version of embedded python. I used latest release for winx64
  • In Unity, create a new folder under Assets called StreamingAssets.
  • Extract the .zip of your downloaded Python into the StreamingAssets folder.
  • To enable pip, download get-pip.py and save it in the Python folder (Assets/StreamingAssets/python-3.9.5-embed-amd64)
  • Run get-pip.py in command line. First cd into Assets/StreamingAssets/python-3.9.5-embed-amd64, then execute
python.exe get-pip.py
  • Now you can install any module you want with
python.exe -m pip install module-name

Final Steps

  • You should go to Edit > Project Settings > Player > Other Settings > Configuration and change the Api Compatibility Level to .Net 4.x to be safe. Apparently there can be some issues using .Net Standard 2.0.

Using Python.NET in Unity

Python.NET in a C# Script

  • In a C# script you will want to include this in the Start() method. This locates the Python.Runtime.dll. You will probably want to use the Soft shutdown mode, as it prevents crashes when using certain Python libraries. https://github.com/pythonnet/pythonnet/pull/958
void Start()
{
    Runtime.PythonDLL = Application.dataPath + "/StreamingAssets/python-3.9.5-embed-amd64/python39.dll";
    PythonEngine.Initialize(mode: ShutdownMode.Soft);
}
  • You will also want a method for shutting down Python.
public void OnApplicationQuit()
{
    if (PythonEngine.IsInitialized)
    {
        PythonEngine.Shutdown();
    }
}
  • You should wrap all of your code in the Py.GIL (Python Global Interpreter Lock) which is a mutex that ensures only one thread has control of the Python interpreter at a time.
using (Py.GIL())
{

}
  • One of the first things you will want to do is import sys.
dynamic sys = PyModule.Import("sys");
  • Now you can add the path of Python scripts to the Path so that you can import them. In this example, I have script.py in the C:/Users/Jacob Bream/Documents/Biomojo/Unipy/Unipy7/Assets/Python directory.
sys.path.append(@"C:/Users/Jacob Bream/Documents/Biomojo/Unipy/Unipy7/Assets/Python");
dynamic scope = Py.Import("script");
  • With the scope variable, you can access variables, methods, classes, etc in the Python script. You will see examples of this in CallingPython.cs

Limitations

  • Currently, haven't figured out a way to get it working with Hololens.
  • Have to be careful to pay attention to types, as conversions don't always work exactly how would think they would.
    • In order to send Arrays to C#, you have to use System.Arrays in Python. You could still use lists in Python, you would just have to ensure you convert it to a System.Array before C# accesses it.

Clone this wiki locally