[Unity] OpenFileDialogをWindowsアプリ(exe)で使う

#Windows向けのツールをUnityで開発
普段からUnityを使っているので、UnityでWindows向けのツールも作ろうと考えた。
そのツールは特定のcsvファイルを選択し、加工するものであった。

この動作には、「ファイル選択」が含まれるので、「ファイルを開く」といったボタンが必要になる。

#ファイル選択ボタンを用意する方法
初心者が気をつけなければいけないのは、UnityEditor関係のやつ。

EditorUtilityは、あくまでUnityエディタ上で動くものであって、
exeにしたら当然動かない。（やり方次第ではコンパイルエラーになる）
https://docs.unity3d.com/ja/current/ScriptReference/EditorUtility.html

つまり今回の目的では使えないということだ。

#OpenFileDialogを使う

Windowsツール用には、OpenFileDialogが使えることを確認した。
https://msdn.microsoft.com/ja-jp/library/system.windows.forms.openfiledialog(v=vs.110).aspx

##コードを書く
まずコードを書く。

まず「ファイルを開く」ボタンを用意する。
次に使うファイル名を表示する「InputField」も用意しておくといいだろう。
そして、以下のScriptを貼り付ける。


```example.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using UnityEngine.UI; //Input Field用に使う
using System.Windows.Forms; //OpenFileDialog用に使う


public class OpenFileButton : MonoBehaviour {

    public InputField input_field_path_;

	// Use this for initialization
	void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
		
	}

    public void OpenExistFile()
    {

        OpenFileDialog open_file_dialog = new OpenFileDialog();

        //InputFieldの初期値を代入しておく(こうするとダイアログがその場所から開く)
        open_file_dialog.FileName = input_field_path_.text;

        //csvファイルを開くことを指定する
        open_file_dialog.Filter = "csvファイル|*.csv";

        //ファイルが実在しない場合は警告を出す(true)、警告を出さない(false)
        open_file_dialog.CheckFileExists = false;

        //ダイアログを開く
        open_file_dialog.ShowDialog();

        //取得したファイル名をInputFieldに代入する
        input_field_path_.text = open_file_dialog.FileName;

    }

}
```

上の説明じゃよく分からんという初心者は、以下のコードを改変して使おう。（さすがにそんな人いないと思うけど)

```example.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using System.Windows.Forms; //OpenFileDialog用に使う


public class OpenFileButton : MonoBehaviour {

    public void OpenExistFile()
    {

        OpenFileDialog open_file_dialog = new OpenFileDialog();

        //ダイアログを開く
        open_file_dialog.ShowDialog();

        //取得したファイル名をstringに代入する
        string file_name = open_file_dialog.FileName;

    }

}
```

##DLLを用意する
このままではSystem.Windows.Formsなんてない　といってエラーを受けるのでDLLを用意する。

System.Windows.Forms.dll

DLLは以下の場所にある。
C:\Program Files\Unity\Editor\Data\Mono\lib\mono\2.0

これをAsset/Pluginsフォルダ(plug-inだっけ？)にコピーする
移動ではない。コピーする。

注意すべきは、絶対に上記の場所から持ってくること。

C:\Windowsあたりから持ってきたら、動かない。

ボタンを押すと
NullReferenceException : Object reference not set to an instance of an object System.Windows.Forms.FileDialog.RunDialogVista
みたいなメッセージを受ける。

こうならないように、必ず上記アドレスのものを使うこと。（読み飛ばしてる奴によくある話だよ！）

##Data folder not found

このままコンパイルすると以下のメッセージを受ける。
"dll is not allowed to be included or could not be found"

そして実際にexeを実行すると、以下のメッセージを受ける
There should be 'ProjectName_Data' folder next to the executable

これはApi Compatibility Levelを変更すると解消できる。

Unityの上側メニューからFile -> Build Settings

Build SettingsメニューからPlayer Settings を押す

Inspectorビューに表示されている[Setting for PC , Mac & Linux Standalone]のタブから
Other Settings -> Optimization -> Api Compatibility Levelの項目を

.NET 2.0 Sub -> .NET 2.0に変更する

これで全てうまくいく。

##おわりに

ここに書いてある問題は全て自分の体験に基づいています。
（つまり英語の文献読んで、めんどくさいから読み飛ばしたら、dll間違えたということですね。HAHAHA）