Unityエディター拡張 ファイルダイアログの表示とCSVの読み込み

# 今回やること
   * ファイルダイアログを[SerializeField]のように簡単に表示できるようにする
   * ついでにCSVファイルの読み込みも行う

## 完成物
![スクリーンショット (33).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414957/915339b5-a445-e788-59fd-b4a1d85fa864.png)

## 諸注意
エディター拡張での[SerializeField]のような属性はEditorという名前のフォルダを作り、その中に追加したいエディター拡張のスクリプトを書きますので
フォルダ名にはご注意ください。

## コード部分
まずはEditorフォルダーに作るものから

```c#:FileDesignation.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using UnityEditor;

/// <summary>
/// Fileを選択するときに使用する属性
/// </summary>
[CustomPropertyDrawer(typeof(FileDesignationAttribute))]
public class FileDesignation : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        FileDesignationAttribute fileAttribute = (FileDesignationAttribute)attribute;
        
        // 使用するプロパティの配置
        Rect rectFileOpenButton = new Rect(position.x + position.width -30, position.y, 30, position.height);
        Rect rectFilePath = new Rect(position.x, position.y, position.width - rectFileOpenButton.width - 5, position.height);
        Rect rectFileExtension = new Rect(position.x + 60, position.y, position.width - 325, position.height);

        // 各プロパティをインスペクターに表示
        EditorGUI.TextField(rectFilePath,label,property.stringValue);
        fileAttribute.extensionFilter = (FileDesignationAttribute.FILEEXTENSION)EditorGUI.EnumPopup(rectFileExtension,fileAttribute.extensionFilter);
        if(GUI.Button(rectFileOpenButton, "..."))
        {
            string directoryPath = ""; 
            string pathName = "";
            if(File.Exists(property.stringValue))
            {
                directoryPath = Path.GetDirectoryName(property.stringValue);
            }

            if(fileAttribute.extensionFilter.ToString() == "NONE")
            {
                pathName = EditorUtility.OpenFilePanel("select ",directoryPath, "");
            }
            else
            {
                pathName = EditorUtility.OpenFilePanel("select ", directoryPath  ,fileAttribute.extensionFilter.ToString());
            }

            // ファイル選択後の処理
            if(!string.IsNullOrEmpty(pathName))
            {
                property.stringValue = pathName;
            }
        }
    }
}
```

次にPropertyAttributeを継承させたスクリプト(言い方は気にしないでほしいです・・・・)
ここからはEditorフォルダの中に入れる必要がないもの

```c#:FileDesignationAttribute.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FileDesignationAttribute : PropertyAttribute
{
    public enum FILEEXTENSION
    {
        NONE = 0,
        CSV = 1,
    }
    // 拡張子フィルター
    public FILEEXTENSION extensionFilter;
}
```


これで属性の追加が完了になります。

次はこれを利用したCSVファイルの読み込み

```c#:CSVReader.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;    // File読み込み用

/// <summary>
/// CSVを読み込むためのクラス
/// </summary>
public class CSVReader : MonoBehaviour
{
    private TextAsset csvFile;
    private List<string[]> csvDatas = new List<string[]>(); // CSVの中身を格納するリスト
    [Tooltip("ファイルパスを格納する変数"),FileDesignation,SerializeField] private string filePath;

    void Start()
    {
        LoadCSV();
    }

    /// <summary>
    /// CSVファイルの読み込みを行う関数
    /// </summary>
    private void LoadCSV()
    {
        filePath = Path.GetFileNameWithoutExtension(filePath);
        csvFile = Resources.Load(filePath)as TextAsset;
        StringReader csvReader = new StringReader(csvFile.text);

        while(csvReader.Peek() > -1)
        {
            string cell = csvReader.ReadLine();
            csvDatas.Add(cell.Split(','));  // ','を目安にリストに格納していく   
        }
        csvReader.Close();
    }
    
    /// <summary>
    /// 読み込んだCSVのデータをすべて受け渡す関数
    /// </summary>
    /// <returns>CSVデータの中身全ての文字列</returns>
    public List<string[]> GetCsvDatas()
    {
        return csvDatas;
    }

    /// <summary>
    /// 読み込んだCSVデータの指定列を受け渡す関数
    /// </summary>
    /// <param name="lineNum">行番号</param>
    /// <returns>CSVデータの指定列の文字列</returns>
    public string[] GetCsvLine(int lineNum)
    {
        return csvDatas[lineNum];
    }

    /// <summary>
    /// 読み込んだCSVの指定されたセルの文字列を受け渡す関数
    /// </summary>
    /// <param name="lineNum">行番号</param>
    /// <param name="columnNum">列番号</param>
    /// <returns></returns>
    public string GetCsvCell(int lineNum, int columnNum)
    {
        return csvDatas[lineNum][columnNum];
    }
}
```

#### 最後に
これめっちゃ便利