Unityから外部プログラム(プロセス)を実行する
About
Unityを実行している最中に、何かしらのアクションをトリガーにして外部プログラムを起動することができます。Unityのみでは実現することができない機能を組み込みたい場合に有効です。ここではWindows上であつかうことのみを想定していますので、他の環境下での試験は行っていません。PC環境下であれば実行できるとは思いますが、定かではない点に注意してください。
- Unity_ExternalTest.zip
- Unity4.0プロジェクト
- 動画ファイルに関する著作権は放棄していません。
- 2次配布などの一切を禁止します。サンプルプログラムのために公開されることをご了承ください。
How to
JavascriptからもC#からも実現することができます。ここではJavascriptで簡単に、C#では応用的にあつかうことにします。またサンプルプロジェクトではこれらのスクリプトをMainCameraにアタッチしています。
Javascriptから簡単に起動
下記のサンプルではアセット中に存在する動画ファイルを再生するパターンと、OSにインストールされたアプリケーションを起動するパターンと2つ用意しています。スペースキーが入力されると起動します。ソースコードの通り、外部プログラムの起動には"System.Diagnostics.Process"クラスを利用します。
if(Input.GetKeyDown("space")){ Debug.Log(Application.dataPath+"/test.wmv"); //アセットファイルを開く(既定のアプリケーションで起動する) System.Diagnostics.Process.Start(Application.dataPath+"/test.wmv"); //インストールされたアプリケーションを起動する System.Diagnostics.Process.Start("notepad.exe"); }
特に難しい点はありませんが、"Application.dataPath"で実行するUnityプログラムのファイルパスが得られる点のみ覚えておけば汎用性が高いので良いと思います。
C#からの起動
少々長いですが、(Javascriptに対して)比較的実用的なレベルになるようにソースコードを書きました。ここまで来るとUnityというより普通の.NetFrameworkのプログラミングなので、Unityで検索するよりもC#で実現する方法を検索するほうが良い記事が見つかるでしょう。
基本的なあつかいに関してはJavasciptと同様です。OSに既存のアプリケーションの指定方法などを変更していますが、実行するファイルやアプリケーションの指定方法については、状況に応じて適切なものを選択すればよいと思います。
サンプルはSpaceキーで外部プログラムを起動し、Enterキーで外部プログラムを終了するようにしています。ここで注意しなければならないのは、外部プログラムを起動すると、Unityのウィンドウは非アクティブになるので、以降のキー入力が全て外部プログラムに入ることになる点です。それ以外に特に注意する点はありませんが、一般的な.Netアプリケーションと同様に、"Exitedイベント"をあつかうことができるのを確認しています。
/// <summary> ///起動する外部プロセス /// </summary> Process exProcess; // Update is called once per frame void Update() { //開始 if (Input.GetKeyDown("space")) { if (exProcess == null) { string path = Application.dataPath + "/test.wmv"; exProcess = new Process(); exProcess.StartInfo.FileName = "C:\\Program Files\\Windows Media Player\\wmplayer.exe"; exProcess.StartInfo.Arguments = path; //外部プロセスの終了を検知してイベントを発生させます. exProcess.EnableRaisingEvents = true; exProcess.Exited += exProcess_Exited; //外部のプロセスを実行する exProcess.Start(); } } //終了 if (Input.GetKeyDown("return")) { if (exProcess.HasExited == false) { exProcess.CloseMainWindow(); exProcess.Dispose(); exProcess = null; } } } void exProcess_Exited(object sender, System.EventArgs e) { UnityEngine.Debug.Log("Event!"); exProcess.Dispose(); exProcess = null; }
もしも一定時間で外部プログラムを停止したいなどの需要がある場合には、Unityの実行状況について注意する必要があります。通常、Unityのウィンドウが非Activeである場合に、Unityのゲーム内時間は停止するからです。