【Unity】【Editor拡張】属性を使ってインスペクターの可視性をちょっとだけ上げる

# はじめに
`[SerializeField]`などでおなじみの属性を使って、インスペクターをちょっとだけ可視性を上げてみます

# 属性の知識
こちらの方の解説が分かりやすくてオススメです

https://www.hanachiru-blog.com/entry/2022/04/20/153950


### ざっくりまとめ
- 簡単なものは基本的に`PropertyAttribute`クラスを継承して作る
- `PropertyDrawer`クラスを継承して、属性を適用したフィールドの描画をする
    - OnGUIメソッドをOverrideして描画する    
    - `CustomPropertyDrawer`属性で描画元の属性を型で指定する
- `AttributeUsage`で属性の対象(フィールド、プロパティ、メソッド)などを変更できたりする

# 注意点
PropertyDrawerはEditorフォルダ、PropertyAttributeクラスの派生クラスはそのほかのフォルダに入れないと、ビルド時にエラーが出ます



# 使用例
### 無効化フィールド
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/8769d8ca-2266-fd98-893a-f3f5f0240b64.png)


- 参考サイトにもあるものです。
- 共同作業とか、デバッグ時のプレビューとかに使えそう

```C#
public class DisableAttribute : PropertyAttribute
{

}

[CustomPropertyDrawer(typeof(DisableAttribute))]
public class DisableDrawer : PropertyDrawer
{

    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        EditorGUI.BeginDisabledGroup(true);
        EditorGUI.PropertyField(position, property, label);
        EditorGUI.EndDisabledGroup();
    }
}

```


### 色付きフィールド
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/39f9fef8-832f-a49f-8bfe-0a525f39c8cc.png)


- 色はRGB(0 - 1)で指定します
    - Colorクラス使えないのもどかしい
    - コンストラクタをintで255ベースのRGBにオーバーロードしてもいいかもね

```C#
public class ColorFieldAttribute : PropertyAttribute
{
    public readonly Color color;

    public ColorFieldAttribute(float r = 1, float g = 1, float b = 0)
    {
        color = new Color(r, g, b);
    }
}

[CustomPropertyDrawer(typeof(ColorFieldAttribute))]
public class ColorFieldDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        ColorFieldAttribute colorField = attribute as ColorFieldAttribute;

        var defaultBGColor = GUI.backgroundColor;
        var defaultColor = GUI.color;

        GUI.backgroundColor = colorField.color;
        GUI.color = colorField.color;
        EditorGUI.PropertyField(position, property, label);
        GUI.backgroundColor = defaultBGColor;
        GUI.color = defaultColor;
    }
}
```



### 区切り線
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/0b4f4b03-06a1-0929-c0b3-aaeb7816c1ff.png)

- 線の太さと空白幅を指定できます

```C#
public class LineAttribute : PropertyAttribute
{
    public readonly float thickness;
    public readonly float padding;

    public LineAttribute(float thickness = 2, float padding = 16)
    {
        this.thickness = thickness;
        this.padding = padding;
    }
}

[CustomPropertyDrawer(typeof(LineAttribute))]
public class LineDrawer : DecoratorDrawer
{
    public override float GetHeight()
    {
        LineAttribute line = attribute as LineAttribute;
        return line.thickness + line.padding;
    }

    public override void OnGUI(Rect position)
    {
        LineAttribute line = attribute as LineAttribute;

        position.y += line.padding / 2;
        position.height = line.thickness;
        EditorGUI.DrawRect(position, new Color(.16f, .16f, .16f));
    }
}
```

# さいごに
グループトグルとか、Particle Systemみたいなトグルリストも気軽に作れる属性欲しいですね(多分属性だと作れない)

あとEditor沼にはまりそうなのでこんくらいにしときます