Unityにスクリプトのコンパイルを依頼するためにどう土下座すれば


概要

Unityで、他のアプリケーションと連携して、特定条件下でビルド/Playを走らせてほしい。

具体的には、デフォのMonoDevやXamarinやSublimeTextなどの外部エディタから、コンパイルを走らせたい。

編集しながら、一定のタイミングでビルドを走らせたい。

オートコンパイルがやりたい。


ビルドのトリガーは、Unity Editor側でも、外部エディタ側でもかまわない。

今は、外部エディタからの制御を可能にしたので、そこからの入力を前提に考えている。



特定条件

求める条件は下記の通り

1.エディタでのファイルの保存、ビルドトリガーの実行(⌘+bとか)をトリガーに、Unityが信号を受け取る

2.トリガーをきっかけに、Unityがビルドを行う

3.Unity以外のアプリにフォーカスが当たっている状態でも発動する

4.Unity.appは起動し、特定のプロジェクトを開いている

5.Unityとエディタは同一マシン上にある


上記条件のうち、1だけはそれ用の機構が必要なので、作った。

エディタの特定動作から、UnityEditor側にトリガーを送り、UnityEditor側もそれを受けることができる。


で、難関なのが、2だった。



実現手段その1

Unityのビルドは、UnityEditorなどの中で、特定のスクリプトを実行すればOK。

EditorApplication.isPlaying = true;


とか。


が、これには制約があり、


制約1.このメソッドは、UnityのmainThreadからでないと実行できない

制約2.今回は外部からの入力という事で、別プロセスでUnityEditorから実行することになるので、実行母体はstaticなScriptになる

制約3.入力経路の関係上、Unityでトリガーを受け取る部分はmainThreadではなく、subThreadになる

制約4. Editor上で、subThreadからUnityのmainThreadに合流するAPIとかすべは無い??(見つけられてない


mainThreadでの動作は、UnityEditorのツールバーとかからクリックで選んだら即OK、なんだけど、、

唯一、

Concurrency kit 

C♯3.5以上の環境で動く、Taskっぽいものが実装してあるAsset

http://u3d.as/content/spicy-pixel/spicy-pixel-concurrency-kit/312


テラシュールさんの判りやすい説明(まるなげ)

http://terasur.blog.fc2.com/blog-entry-341.html



が、対今回の用途として凄くいいとこまで行ってるんだけど、制約2 Editorのスクリプトがstatic前提 のため、

肝心なところでエラーが出る。


具体的に書くと、taskFactory.StartNew(Createobject()); が、taskFactoryがstaticじゃないので利用できずに詰む。


このライブラリはstatic前提で書かれていないんだわー。 だわー。ゎ_. →ちゃんとAPI読んだらそんなことないかもしれないよ? って言われたので後で読む。

→ここから派生する別の解決策として、Unityにフォーカスが当たっていないタイミングでも定期的に動き続ける

UnityEditorのフックを探す、という手も考えられるんだけど、そんなの無さそう。見つけられてない。


実現手段その2

ほかの手段として、

Unityのバッチを使用する手段も有るんだけど、こちらにも問題がある。


下記のようにUnityのプロセスをバッチを介して動かせるが、

/Applications/Unity/Unity.app/Contents/MacOS/Unity -batchmode -executeMethod BuildBatch.Build

とか。主にCI上で利用している。-quitで毎回終了させる事もだいじ。


これが動くためには、Unity.appがバッチ内容の対象のプロジェクトを開いていない 必要がある。 条件4への明らかな違反。


無視して動かそうとすると、「ちょwwなんか既に起動してるんですけどwww」なエラーを吐く。 ファーーーーーーwwwww


こんなエラー。

Aborting batchmode due to failure:

Fatal error! It looks like another Unity instance is running with this project open.

Multiple Unity instances can't open the same project.


今回の用途としては、実行したり編集したりしながらビルドしたいので、詰んでる。Unity起動してないとすぐ遊べない。

→対象となるプロジェクトを設定したらどうなるん?

駄目でした。 Unityは全く悪くない。俺が変な事しようとしてる。 先生ー! 俺君がへんなことしてます!



妥協の上での実現手段

いまのところ、下記2つの手段で、実用レベルとして妥協しまくりだが、実現している。


手段1.保存時トリガーをUnityが自動検知してビルドするのを利用する

Unityからファイルを開くと、エディタでのファイル保存時にビルドが走ってくれる。

Macのファイル監視イベントをつかってるっぽい。


→Unityが変な開き方するので、だいぶ辛い。一回で検知しないことが稀によくある。


多分、汎用化のために、


1.アプリケーション起動コマンドを実行

2.そのアプリケーションにファイルパスを渡す


とかを行ってるんだろうなーと思うなど。

それにしても認識しない。最初の一回は絶対に認識しない。 なによりシングルファイルで開いちゃってとてもダサいので逃げ出したい。



手段2.Unityにフォーカスが移った瞬間ビルドが発生するのを利用する

一瞬だけUnityにフォーカスを持って行くことでも自動的にコンパイルが走る。

っていうか現在、一番まともな代替手段がコレ。


→やってみたところの動画

https://vimeo.com/61986887


保存をトリガーにしていて、ファイルを保存するとパパッとフォーカスが移動して、、、つらい、、、、

なにかの宗教的儀式みたいだ、、 なにかの宗教的儀式に従事されてる方すいません、、


上記を満たす実行可能手段を探しています

たすけてください! たす、、け、、