Table of Contents

Unity Hub as tool to install old Visual Studio community edition

Python for Unity

ref:

Instruction

Python and Qt inside Unity

Once above basic setup for python is done for unity, I would like to get Qt working and interaction with unity.
(Note, don't launch python Qt code from Python Console inside Unity, it will show Qt window, but it also block Unity UI interaction, run it from c sharp script)

After a bit research, mainly from video of Indie-Pixel's Python for Unity 3D 2020!!: (https://www.youtube.com/watch?v=3UOlN8FcNbE)

I got it further into make the PySide2 UI interaction working. the main thing is print(). you need to

import UnityEngine as unity
unity.Debug.Log("use this way of print in unity when run from python script")

Steps:

  1. create a empty PyTool.cs for attaching to a GameObject
  2. create a PyToolEditor.cs for making buttons to launch those python script file, and PyToolEditor.cs is actual interface (so called UI file) of PyTool.cs
  3. so depends on how many python scripts to launch, you make how many button inside PyToolEditor.cs
  4. I created 2 .py examples, one without UI, one with Qt UI
  5. I put 2 python script inside Assets's “PythonScript” folder
  6. PythonScript/UnityPythonRun.py is a simple test python script to query info, (but this time, it is from script, code a bit different from PythonConsole inside Window>General>Python Console)
  7. PythonScript/TestQ.py is a simple Qt UI python tool with a Qt button to do some query unity info.

PyTool.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class PyTool : MonoBehaviour
{
 
}
PyToolEditor.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.Scripting.Python;
 
[CustomEditor(typeof(PyTool))]
public class PyToolEditor : Editor
{
    PyTool targetTool;
    private void OnEnable()
    {
        targetTool = (PyTool)target;
    }
    public override void OnInspectorGUI()
    {
        if (GUILayout.Button("PyTool", GUILayout.Height(35))) {
            Debug.Log("Hello PyTool");
            string cur_path = Application.dataPath;
            Debug.Log(cur_path);
            string py_file = cur_path + "/PythonScript/UnityPythonRun.py";
            Debug.Log(py_file);
            PythonRunner.RunFile(py_file);
        }
        if (GUILayout.Button("TestQ", GUILayout.Height(35)))
        {
            Debug.Log("Hello TestQ");
            string cur_path = Application.dataPath;
            string py_file = cur_path + "/PythonScript/TestQ.py";
            Debug.Log(py_file);
            PythonRunner.RunFile(py_file);
        }
    }
}
UnityPythonRun.py
import UnityEngine as unity
def u_print(info):
    unity.Debug.Log(info)
 
obj_list = unity.Object.FindObjectsOfType(unity.GameObject)
for each_obj in obj_list:
    print(each_obj.name)
    u_print(each_obj.name)
print('python here')
u_print('python here')
TestQ.py
import UnityEngine as unity
from PySide2 import QtWidgets
class TestUI(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        QtWidgets.QMainWindow.__init__(self, parent)
        # win
        self.setWindowTitle("TestQ")
        # ui part
        main_widget = QtWidgets.QWidget()
        self.setCentralWidget(main_widget)
        main_layout = QtWidgets.QVBoxLayout()
        main_widget.setLayout(main_layout)
 
        test_btn = QtWidgets.QPushButton("List Object")
        main_layout.addWidget(test_btn)
        # connection
        test_btn.clicked.connect(self.list_items)
    # function
    def list_items(self):
        print('hello in python, not shown in unity. - from TestQ')
        self.u_print('hello in unity. - from TestQ')
        obj_list = unity.Object.FindObjectsOfType(unity.GameObject)
        for each_obj in obj_list:
            self.u_print(each_obj.name)
    def u_print(self, info):
        unity.Debug.Log(info)
# fix QApplication singleton issue for run python inside some app
if not QtWidgets.QApplication.instance():
    app = QtWidgets.QApplication([])
else:
    app = QtWidgets.QApplication.instance()
main_ui = TestUI()
main_ui.show()

About Unity

Structure of Unity

Shortcut

viewport navigation alt-based Mouse navigate, RMB-hold WASD key navigate
focus on selected f
snap obj to view pos ctrl+shift+f (good for cam to cam match)
max view shift+space (like max)

Customize view

asset panel slide <left to list, >right to grid view

C# Script's attribute process timeline

  1. C# script's public attribute default value is the factory default value
  2. C# script's start() attribute change is game start initial setting
  3. once C# script in unity are dragged into Game Object, it is under Unity Game maker's control in Inspector panel, if game maker make a new value there, it is baked into game project for that inspector object (however, if start() has value overwrite, then the game will always be initialized with start() value, game maker still can make change to test it but start() will replace on start)

C# common code for Unity

Common package

Pipeline Connection