PaperSloth’s diary

Unity(C#)、UE4(Blueprint/C++)についての記事を書いたり日常のことをつぶやきます。

Unity開発応用3(Unityから外部アプリケーションの実行)

こんちは!


f:id:PaperSloth:20150603002612j:plain
今回は飛び出せUnityな記事を書いていこうと思います。
Unity4系でも動作する拡張となっております。
今回使用するのはUnity5.2.1p2です。

特にUnityから飛び出すわけではありませんが、
拡張を行うことでUnity上で幾つかの作業を行うことができるようになると思います。

目次

・Unityから外部アプリケーションを起動してみる
・独自のbatやコンバータもUnityから起動したい場合
 (個人開発向け、まだまだ改善の余地あり)
・もう少し仕事、チーム開発向けにするには(僕はやらない
・まとめとコード

・Unityから外部アプリケーションを起動してみる

 Unityから外部アプリケーションを起動するのはとても簡単です。
 UnityというよりはC#の機能になります。

 Processクラスを使用してアプリケーションの起動から終了まで待機する
 Processクラス:https://msdn.microsoft.com/ja-jp/library/system.diagnostics.process(v=vs.110).aspx

 System.Dianostics内にあるため、using定義するか
 System.Dianostics.Processと定義しましょう。


 外部アプリケーションの起動とは
 簡単な例でいうと、ファイル名を指定して実行( Windowsキー + R )が伝わりやすいでしょうか?
 そこでcmd.exeと入力すれば、コンソールが立ち上がると思います。

コード例:コンソール立ち上げ
System.Dianostics.Process process = new System.Diagnostics.Process();
process.StartInfo.Filename = "cmd.exe";
process.Start();
process.WaitForExit();

 たったの4行でできちゃいます。
 簡単ですね。
 StartInfo.Filenameで起動するアプリケーション名の指定
 Startで起動
 WaitForExitでアプリケーション終了まで待機

※ここで一つ注意点

 WaitForExitで待機している間、Unityを操作することができなくなります。
 そのため、長時間変換に時間がかかるような外部のツールによるデータ変換処理などには向いていない。

簡単な拡張の例
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;

public class BootExternalApplication
{
    // UnityのMenubarにカスタムを作成。
    // Custom部分をAssetsとすることでProjectViewからの呼出しができて便利
    // ( ProjectViewから右クリックで呼び出し可能となるため )
    [MenuItem( "Custom/Application/Console" )
    public static void OpenConsole()
    {
        System.Dianostics.Process process = new System.Diagnostics.Process();
        process.StartInfo.Filename = "cmd.exe";
        process.Start();
        process.WaitForExit();
    }
}

・独自のbatやコンバータもUnityから起動したい場合

 (個人開発向け、まだまだ改善の余地あり)

 先ず、ファイル名を指定して実行( Windows + R )で呼び出すのと同じような仕組みを作る。
 手順①
  CドライブやDドライブなど任意の場所にアプリケーション登録用のフォルダを用意する。
  ファイル名はCustomApplicationとか
f:id:PaperSloth:20160204222606p:plain

 手順②
  システムプロパティの起動
  ファイル名を指定して実行( Windows + R )から
  sysdm.cplを実行
f:id:PaperSloth:20160204222307p:plain

 手順③
  詳細設定から環境変数の追加。
  詳細設定内の環境変数から"ユーザー名"のユーザー環境変数で新規を押す。
  変数名:path
  変数値:C:CustomApplication( 先ほど作成したファイルパス、ファイル名 )
f:id:PaperSloth:20160204223439p:plain

f:id:PaperSloth:20160204223714p:plain

f:id:PaperSloth:20160204223551p:plain


 手順④
  先ほど登録した場所に起動したいアプリケーションや
  アプリケーションのショートカットなどを登録する
f:id:PaperSloth:20160204222755p:plain

例:Skypeのショートカットを立ち上げる( 絶対Unityからは使わないと思うけどw )
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;

public class BootExternalApplication
{
    [MenuItem( "Custom/Application/Skype" )
    public static void OpenSkype()
    {
        System.Dianostics.Process process = new System.Diagnostics.Process();
        // ショートカットの実行はexeではなく.lnkです
        process.StartInfo.Filename = "skype.lnk";
        process.Start();
        process.WaitForExit();
    }
}

・もう少し仕事、チーム開発向けにするには(僕はやらない

 先ほどのツールへのショートカットパス設定をツール等を作成して、簡単に行えるようにする
 システムの環境変数追加とかをなんだか敷居が高い、めんどくさいと思う人がいる
 あと間違いを防ぐ意味でもツール化できると便利


 パスの設定や起動アプリケーションを
 Unity Preferencesからも編集可能にする
 これはPreferencesの拡張で直ぐにできます。


 毎回コードを書いたりするのでは不便すぎる
 アプリケーションのパスの設定のみで呼出し可能になるなど、
 コードを改変するコードを書く( できるかは知らない )


・まとめとコード

 引数にコマンドを指定して呼び出すことも可能なので、
 任意のアプリケーション起動と共にコマンド実行が可能。
 例えば、SVNのUpdateを行うなど

 因みに僕はcmd.exeのコマンドにexitを入れるという何もしないテストコード書いてましたw

using UnityEngine;
using UnityEditor;
using System.Collections.Generic;

public class BootExternalApplication
{
    [MenuItem( "Custom/Application/TortoiseSVN/Update" )
    public static void Update()
    {
        StartApplication( "TortoiseProc.exe", "update" );
    }

    /// <summary>
    /// 外部アプリケーションを起動する
    /// </summary>
    /// <param name="filename">アプリケーション名</param>
    /// <param name="command">コマンド</param>
    private static void StartApplication( string filename, string command = "" )
    {
        System.Diagnostics.Process process = new System.Diagnostics.Process();
        process.StartInfo.FileName = COMMAND_PATH + filename + LINK;
        if( !string.IsNullOrEmpty( command ) )
        {
            process.StartInfo.Arguments = "/command:" + command;
        }
        process.Start();
        process.WaitForExit();
        return;
    }
}

以上です!

ではまた