動機
UnityにはUnityEngineUIがあり、ボタンやテキストボックスを実装することができます。
ただ、Unityを使ったエディタを作ろうとしたときに、このUIの仕組みでは少し力不足に感じますし、とても使いにくい印象です。 UIのデザインもデフォルトだと「ザ・Unity」感が出てあまり好きではありません。
そこで、ビューワとしてUnityのStandaloneを使い、UIをQtにて実装できないかと思い調べました。
環境 | |
---|---|
Unity | 2019.2.19f1 |
Python | 3.7.5 |
PySide2 | 5.14 |
OS | Windows10 |
注意
- Windows限定です。
- Unityが古いと標準出力エラーが得られないようです。
Unity2018.4.20f1
で最初は試していましたが、標準エラー出力がキャッチできませんでした。Unity2019.2.19f1
にバージョンを上げたところ、Unityからの標準エラー出力を受け取ることができるようになりました。
下準備
UnityでPC Standaloneビルドを行います。また、UI側とパイプで通信するため、標準入力を画面に表示し、受け付けた後標準エラー出力へSTDERR
をプレフィックスとしてエコーするようなプログラムを作成します。
Windowsの場合、Unityの中から書き出した標準出力はファイルにダンプされます。
(C#コードを載せますが、C#は全く書けないので真似しないほうが良いかも)
using System.Collections.Concurrent;
using UnityEngine;
using System.Threading;
using System;
public class inout : MonoBehaviour
{
static BlockingCollection<string> queue = new BlockingCollection<string>();
Thread t;
[SerializeField] UnityEngine.UI.Text text;
private static void ThreadProc() {
try {
while (true) {
var stdin = Console.ReadLine();
if (stdin == null) break;
queue.TryAdd(stdin, Timeout.Infinite);
}
}
catch (Exception) { }
}
private void Start() {
t = new Thread(new ThreadStart(ThreadProc));
t.Start();
}
private void OnGUI() {
string data;
while (queue.TryTake(out data)) {
text.text += data + "\n";
Console.Error.WriteLine("STDERR> " + data);
Console.Error.Flush(); // 念のため
}
}
}
GameObject/UI/Text
をシーンに配置し、 Inspectorからパラメータを以下のように調整しました。
後は適当なGameObject
を作って配置し、先ほどのスクリプトをアサイン、項目text
へ先ほど作成したテキストUIをアタッチします。
PySide側
python -m venv testenv
testenv\Scripts\activate
pip install pyside2 pywin32
1ファイルで簡単なUIを構築します。pywin32はwindows apiを使用するために使います。
閉じるときのスレッドの処理はお粗末ですがしていません。
動作
- ウィンドウサイズを変えると追従します
- 文字を打ち込むと画面に表示され、そのまま標準エラーへエコーされている様子が確認できます