【Unity Editor拡張】アセットの保存してあるパスを取得する

# 概要
- ScriptableObjectやPrefabなど特定のパスに置きたい場合があります
- そのチェックのためにEditor拡張を使ってアセットのパスを取得し、利用する方法です

# ScriptableObectのサンプル
```cs
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif

//CreateAssetMenu属性をつけるとメニューからScriptableObjectを作成できるようになる
[CreateAssetMenu(menuName = "ScriptableObject/SamplePathScriptableObject", fileName = "SamplePathScriptableObject.asset")]
public class SamplePathScriptableObject : ScriptableObject
{
    public string SampleString;

    public int SampleInt;
}

#if UNITY_EDITOR
//CustomEditor属性でInspectorのEditor拡張が行える
[CustomEditor(typeof(SamplePathScriptableObject))]
public class SamplePathScriptableObjectInspector : Editor
{
    public override void OnInspectorGUI()
    {
        //元のInspectorを表示する
        base.OnInspectorGUI();

        //InstanceIDからObjectを取得する
        var obj = EditorUtility.InstanceIDToObject(target.GetInstanceID());

        //取得したObjectからアセットのパスを取得する(拡張子あり)
        var path = AssetDatabase.GetAssetPath(obj);

        if (string.IsNullOrEmpty(path))
        {
            return;
        }

        //HelpBoxでパスを表示する
        EditorGUILayout.HelpBox(path, MessageType.Info);
    }
}
#endif

```

メニューからScriptableObjectを作成すると、ScriptableObjectのプロジェクト内でのパスがInspector内に表示することができます
![スクリーンショット 2021-07-23 16.24.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105021/6439d87a-095d-2206-d949-7b787f65689c.png)


![スクリーンショット 2021-07-23 16.17.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105021/1b413f91-7eb1-eff0-bf01-dc7d649dd7a3.png)

# Prefabのサンプル
```cs
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif

public class SamplePrefab : MonoBehaviour
{
    [SerializeField]
    string SampleString;

    [SerializeField]
    int SampleInt;
}

#if UNITY_EDITOR
[CustomEditor(typeof(SamplePrefab))]
public class SamplePrefabObjectInspector : Editor
{
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();

        var obj = EditorUtility.InstanceIDToObject(target.GetInstanceID());

        var path = AssetDatabase.GetAssetPath(obj);

        if (string.IsNullOrEmpty(path))
        {
            return;
        }

        EditorGUILayout.HelpBox(path, MessageType.Info);
    }
}
#endif
```

Prefabの場合も同じようにアセットのパスを表示することができます
![スクリーンショット 2021-07-23 16.27.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105021/68077ac2-845c-179f-1ecd-ff21703f4f2c.png)

# 応用篇　特定のパス以外に置いた場合に警告を出す
必ず特定の位置に設置したいアセットの場合、今回の機能を応用してチェック機構を実装することができます

```cs
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif

[CreateAssetMenu(menuName = "ScriptableObject/SamplePathScriptableObject", fileName = "SamplePathScriptableObject.asset")]
public class SamplePathScriptableObject : ScriptableObject
{
    /// <summary>
    /// アセットの正しい保存パス
    /// </summary>
    public const string ASSET_PATH = "Assets/Resources/ScriptableObject/SamplePathScriptableObject.asset";

    public string SampleString;

    public int SampleInt;
}

#if UNITY_EDITOR
[CustomEditor(typeof(SamplePathScriptableObject))]
public class SamplePathScriptableObjectInspector : Editor
{
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();

        var obj = EditorUtility.InstanceIDToObject(target.GetInstanceID());

        var path = AssetDatabase.GetAssetPath(obj);

        if (string.IsNullOrEmpty(path))
        {
            return;
        }

        if(path != SamplePathScriptableObject.ASSET_PATH)
        {
            var message = $"アセットのパスが間違っています\n{SamplePathScriptableObject.ASSET_PATH}に保存してください";
            EditorGUILayout.HelpBox(message, MessageType.Error);
        }

        
    }
}
#endif

```

![スクリーンショット 2021-07-23 16.59.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105021/413d4370-35f7-a969-5e3e-af503472e7e7.png)

今回の場合はInspectorにエラーを出すだけでしたが、もっと明確にエラーを出したい場合はダイアログを表示したり`Debug.Assert`を使うのもいいでしょう。