UnityのStreamingAssets内でPython環境構築してみた
Pythonで作られたライブラリなどをUnityでも流用したい!
ということで思いついたのがPythonに必要なファイルを全て StreamingAssets
に突っ込む方式でした。
その前にクライアント/サーバーでやり取りしろよ!って話ではあります。はい。その通りです!ただスタンドアローンで動かしたかったんです!!
PythonとC#のやり取りをする
C#との連携で他にもツールは出てきたのですが最終的にPythonのライブラリも使いたいと思っており、探すとPythonnetならできるという情報があったので選出しました。
GithubのWikiに導入方法などは書いておりスムーズに導入できました。dllをダウンロードしてPluginsディレクトリに入れるだけですね。
中身を弄る必要があればGitHubから簡単にcloneしてdefineを弄ればUnityで動かすカスタムができる印象でした。
突っ込むPythonの環境を取得する
Pythonの環境はAnacondaで取得した環境をStreamingAssetsに入れることにしました。 Pythonのインストールパスを確認してから
Python |---------DLLs |---------Lib |---------Scripts |-たくさんのdllとpyファイル
をUnityのStreamingsAssetsに入れます。基本的に必要なものは上記でした。他のディレクトリは無くても大丈夫です。
Editorでは動きます。
Editor/Buildの違い
Unity Editorでは Plugins
ディレクトリ以外にdllがあっても読み込んでくれます。そのため StreamingAssets
にPythonのすべてを入れておくだけでPythonが動きます。しかし、BuildをしてStreamingAssetsにPythonを入れてもdllを検知できません。そのため、Pythonを動かすのに必要なdllをPluginsにいれて他の.pyなどをStreamingAssetsに入れることで解決しました。
そのためdllを全てPluginsに入れて他をStreamingAssetsに入れるようにします。細かいことを気にしなければ全部 Plugins
と StreamingAssets
に入れてしまいます。
ちゃんと分けたい場合は
StreamingAssets
で
find . -name "*.dll" -type f | xargs rm
などをして必要な拡張子だけを残すようにします。
Plugins
だと exe
や py
など dll
以外を消す必要があります。(Windowsだと)
動かした結果
using周りは端折りますが以下のコードを動かしました。(.Net4.0環境)
public class PythonLifeCycle : IDisposable { public void Initialize() { var pythonHome = $"{Application.streamingAssetsPath}/PythonEnv"; var scripts = $"{pythonHome}/Scripts"; Environment.SetEnvironmentVariable("PATH", $"{pythonHome};{scripts}", EnvironmentVariableTarget.Process); Environment.SetEnvironmentVariable("DYLD_LIBRARY_PATH", $"{pythonHome}/Lib", EnvironmentVariableTarget.Process); PythonEngine.PythonHome = $"{pythonHome}"; PythonEngine.PythonPath = $"{pythonHome}/Dlls;{pythonHome}/Lib;{pythonHome}/Lib/site-packages"; PythonEngine.Initialize(); } public void Dispose() { PythonEngine.Shutdown(); }
private readonly PythonLifeCycle lifeCycle = new PythonLifeCycle(); [SerializeField] private TextMeshProUGUI textUI; void Start() { lifeCycle.Initialize(); RunPython(); } private void RunPython() { using (Py.GIL()) { dynamic sysModule = Py.Import("sys"); textUI.text = sysModule.version; } } private void OnDestroy() { lifeCycle.Dispose(); }
シンプルにPythonの環境を構築してTextを出力するようにしています。
Editor | Windows |
---|---|
最低限Editor/Buildでの差は埋めれました。 他(WebGL/Android)はそのまま動かなかったので放置しています。一旦はWinのみで開発するつもりだったので。 触った感じだとデスクトッププラットフォームだと問題ないと思います。
WebGLで実行とエラーがでるのですがパッとうまい解決策が見つけれず放置 Androidでビルドしてgradleの処理の際にStreamingAssetsのファイルが多すぎてファイルをすべてgroovyのファイルに記述されていて、その記述されている数が多いことでエラーとなり失敗します。これはzipに纏めるなりの回避をすればなんとかなるとは思います。(メモ)
まとめ
今後はpythonのライブラリを導入してC#から使えるようにしていこうと思います。1プラットフォームでもPythonを内蔵して動いて良かったです。