UnityでPythonを使うことができるPython Scripting packageというものがあります。公式の説明はこちらです。
公式の説明だけではなかなかできませんでしたが、Python for Unity 3D 2020!!というYoutube動画を参考にして何とかできました。
ただ、この動画はPython2.7.16の環境構築でしたので、Python3で動かすにはまた少し苦労しました。そこで、ここに忘備録を残しておきます。
Pythonの環境構築
Python3.8.3 を、C:\Python38\にインストール(公式ではPython3.10.6としてあるが、すでに入れていたPython3.8.3でもできた)。
環境変数のPath にC:\Python38\ を追加(すでにしてあった)。
コマンドプロンプトから、Pytho3.8.3が実行できることを確認。
[code]
C:\Users\itoma>python –version
Python 3.8.3
[/code]
Unityでプロジェクト作成
2021.3.6f1 で、3Dのアプリケーションでプロジェクト「231001_PythonForUnity」を作成。
Pytohn Scripting というパッケージを入れればよいのだが、いつものPackage Manager からは入れることができない。
そこで次のようにする。
Unityで作ったプロジェクト「231001_PythonForUnity」のディレクトリから以下のファイルをVSCodeなどで開いて、ハイライトしている一行「”com.unity.scripting.python”: “7.0.1”, 」を加える。
\231001_PythonForUnity\Packages\manifest.json
これでUnityに戻ると、自動でPython Scripting がインストールされるのでこれでOK。
Window > Package Managerで、Packages: Unity Registry のリストに「Python Scripting」が入っていることが確認できる。
Python Script Editor
Python Scripting が入ると、以下の3つの使い方ができる。
1.Python Script Editor を使う
2.Unity のC#のコード中にPythonコードを書くPythonRunner .RunString
3.Pythonファイルを読み込んで実行する、PythonRunner.RunFile
以下、Pyton Script Editor の使い方を紹介する。
Window > General > Python Script Editor で、Python Script Editor を開く。
Python Script Editor は、下のような2段組みのUI。下のboxにPythonコードを書いて「Execute」を押すと、実行結果が上のboxに表示される。
例えば、hello Unity。
変数を使った計算もできる。
UnityEngine というパッケージをimport すると、UnityでのObjectの情報をとったり、Objectの操作をすることができる。下のコードを実行すると、Unity上にあるすべてのGameObjectの名前をコンソールに表示する。
import UnityEngine as ue objects = ue.Object.FindObjectsOfType(ue.GameObject) for obj in objects: ue.Debug.Log(f"Pythonから出力 >> {obj.name}")
下は実行例。コンソールにライトとカメラの名前が表示されている。
ちなみに、Loadのボタンを使うと、pyファイルをエディターにロードすることもできる。
冒頭で述べたように、Python script editor を使う方法以外に、Unity のC#のコード中にPythonコードを書くPythonRunner .RunString という方法と、Pythonファイルを読み込んで実行する、PythonRunner.RunFileという方法もある。詳しくは、公式HP参照。
ただ、これら3つの方法は、PythonとUnityを並列に走らせることはではなく、Pythonの処理が終わるのをUnityが待つような形になるようだ。
実は、Unityで作ったロボットをPythonで逐次動かせないかと考えて調べていたのだが、それはできなさそうだ。
例えば、Unityでcubeを作って、下のコードをアタッチするとする。外部から、moveUp()が呼ばれれば、cubeが上に上がり、moveDown()が呼ばれれば、cubeが下がる仕組みだ。
# Controller.cs using System.Collections; using System.Collections.Generic; using UnityEngine; public class Controller : MonoBehaviour { float dy = 0.5f; public void moveUp() { transform.position += new Vector3(0, dy, 0); } public void moveDown() { transform.position += new Vector3(0, -dy, 0); } }
そして、Python Script Editor で以下のコードを実行する。moveUp()の後に、1秒したからmoveDown()を2回コールするという内容だ。cube が上に上がってから一秒後に、下に2つ分下がるという動きを期待している。
import UnityEngine as ue import time objects = ue.Object.FindObjectsOfType(ue.GameObject) for obj in objects: if obj.name == "cube": controller = obj.GetComponent("Controller") controller.moveUp() time.sleep(1) controller.moveDown() controller.moveDown()
しかし、これを実行すると、cubeは下に1つ分動いただけだった。つまり、逐次実行されるのではなく、一気にまとめて実行されているということになる?
まだ十分に理解していないが、ロボットを動かすのには向いていなさそうという印象だった。
コメントを残す