【Unity】自作Editor拡張で固めた開発環境を紹介してみる

# はじめに
手元でパッと開発したい時ありますよね、そういったときに素早く開発できるようにある程度自分の作業環境はあらかじめ整えて置いたほうがいいと思っています。

そのために自分で開発した作業環境を紹介してみようと思います。

基本的にShaderの開発をすることが多いのでグラフィック関係が多いです。
また、Editor拡張以外のShader開発環境はこちらに書いてあります。

https://qiita.com/ayaha401/items/034ddc38ba6232e72106

ShaderをどんなIDEを使っていたり、拡張機能を入れているのか紹介されています。
2年ぐらいたっていますがほぼ変わっていません。


また、紹介方法は以下のように紹介します
* ツール名(見出し)
* ソースコード(存在すれば)
* 内容

# 前提
自作ツールたちがいろいろな場所に散乱しないように命名を固定してます。

まず、Editor拡張やTool周りはAyahaGraphicDevelopToolsから始めるルールにしています。
```C#
namespace AyahaGraphicDevelopTools.HogeHoge
```

よってスクリプトを配置するパスも固定されています。
**Assets/Editor/AyahaGraphicDevelopTools**
に入れます。

同様にEditor拡張のためにMenuItemも固定しています。
```C#
[MenuItem("AyahaGraphicDevelopTools/HogeHoge")]
```
このように決めることで作った者たちが迷子にならない工夫です。

# URPShaderTemplates

https://github.com/ayaha401/URPShaderTemplates

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608797/abdaaa95-02e0-4ec5-8213-840ccf731385.png)
あらかじめ作っておいたShaderのテンプレートをダウンロードできるツールです。
ダウンロードボタンを押すと中には直接リポジトリのリンクからShaderのファイルをDLする処理がかかれており、OutputPathにダウンロードされます。

https://github.com/ayaha401/Shader-ColorFunction/blob/main/ColorFunction.hlsl

上記がDL先のソースコードになっています。
DLしたコードの中身はHLSLスクリプトになっており、メソッド単位で作成されています。
よく使うコードなどがまとまっており、これで開発速度を上げています。

```C
// RGBカラーからHSV色空間のV（明度）を計算
// rgbCol : RGBの色
float getValueColor(float3 rgbCol)
{
    return max(max(rgbCol.r, rgbCol.g), rgbCol.b);
}
```
こちらですとRGBからHSVのVを計算する方法がメソッドになっています。
こういったメソッドの塊を
* Wave
    * 波を作るための関数
* Noise
    * ノイズを作成するための関数
* Curve
    * 曲線を導くための関数
* Macro
    * よく使うマクロを集めている
* MathFunction
    * 数学を使いそうな関数
* ColorFunction
    * 色を求めるための関数
* SDF
    * SDF(距離関数)の関数
* GraphicFunction
    * フレネル反射などグラフィック関係でよく使う関数
現状このような単位で区切っています。
これをワンクリックでDLします。

ダウンロードのほかに、テンプレートを使用してShaderのスクリプトのテンプレートを作成する機能もあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608797/7eede884-89a1-f7e6-1a34-49e8a1ad9f23.png)
HLSL Template
UI Default Shader(URP)
Unlit Shader(URP)の3項目がこのツールで追加されるテンプレートで、すぐにShaderを書き始めれるようになります。

# PreviewTextureMaker

https://github.com/ayaha401/PreviewTextureMaker

Materialに設定されたShaderを利用してTextureを生成できるEditor拡張になります。
ちょっとしたShaderを作成した際に毎回ノイズテクスチャを用意したり、ちょっとしたマスクテクスチャを作成するのってめんどくさいですよね。
それを解決するのがこのツールです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608797/1ef5add9-4490-c163-c511-f88f5ea26a67.png)

マテリアルからテクスチャを生成できます。
ノイズテクスチャが必要になったら、**URPShaderTemplates**からノイズテクスチャを作成するノイズ関数を呼び出しノイズを生成するShaderを書き、マテリアルを作成、**PreviewTextureMaker**を使用してノイズテクスチャを生成といった流れてUnityから離れずに作業ができます。

こちらのツールはマテリアルからテクスチャを生成するため、Shaderでパラメータを外だししておけばこのツールからパラメータを調整してパラメータを調整してすぐに数種類のパターンのテクスチャを生成することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608797/18722912-81ee-4ea2-b303-f304cffceb36.png)

テクスチャのサイズはよく使いそうなサイズから選択したり、自分の好きなサイズで出力できます。

# TextureConverter

https://github.com/ayaha401/TextureConverter

こちらのツールを使用すると最大4枚のテクスチャのRGBA要素を組み合わせて1枚のテクスチャをコンバートできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608797/be2a7fd6-8b4a-fb32-6c30-9292a6862f47.png)

4枚のテクスチャをそれぞれRGBAの各チャンネルに限定して表示させつつコンバートできるのがこれの良い点です。
**PreviewTextureMaker**で作成した4種類のテクスチャを**TextureConverter**を使用してコンバートして1枚に圧縮といった作業がこのツールたちを使うことで可能となります。

# ShaderPropertyClassGenerator

https://github.com/ayaha401/ShaderPropertyClassGenerator

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608797/b8fb2592-b3f5-ba8a-c28e-36499c592d80.png)

前まではShaderを利用してShaderやマテリアルのための素材をUnityから離れずに素早く作るためのツールでしたがこちらはShaderを書いた後C#側で困ることを解決します。

Shaderに使われているPropertyにアクセスするために
```C#
Shader.PropertyToID("_MainTex");
```
を使用してSetやGetを行いますが、`_MainTex`この部分はどうしてもStringになりますし、1文字でも間違えたらアクセスできません、また、Constなどでこれらを定義しますがPropertyが増えるほどめんどくさいです。

そのため、ツールを使用して一括でクラスを作れるようにするのがこちらの**ShaderPropertyClassGenerator**です。

Shaderから自動でPropertyを取得してクラスにするのでString部分を間違えてしまうことがありません。
また、クラスも作れますし、一部のコードのみを選択してクリップボードに保存することもできるため、一度作成したクラスに新たにPropertyを追加するのも自由にできます。

# CSTemplates

https://github.com/ayaha401/CSTemplates

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608797/bc13e4dc-415b-2852-c9e2-9980f2549a91.png)

こちらは**URPShaderTemplates**のC#番です。

* GameObjectUtility
* PrefabUtility
* Extensions
をそれぞれ機能ごとに1つにまとめたクラスをGitHubからダウンロードできます。

GameObjectUtilityではGameObjectに関係する操作をまとめたクラスがあります。
```C#
/// <summary>
/// Scene上の親オブジェクトを全部返す
/// </summary>
public static GameObject[] GetSceneRootGameObjects()
{
    var activeScene = SceneManager.GetActiveScene();
    return activeScene.GetRootGameObjects();
}
```

Scene上の親オブジェクトを全取得できたりなど、1度は書くもののいつか同じものを作ろうとして書き方を忘れそうなものをまとめています。

同じようにPrefabUtilityでは主にPathからPrefabがあるかを調べるようなメソッドを書いています。
```C#
/// <summary>
/// 指定されたパスからプレハブを読み込む
/// </summary>
/// <param name="path">Path</param>
public static GameObject LoadPrefabFromPath(string path)
{
    GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
    if (prefab == null)
    {
        Debug.Log($"{path}にGameObjectがありません");
        return null;
    }

    return prefab;
}
```

Extensionsではまだ数は少ないですが拡張メソッドを入れています。
```C#
/// <summary>
/// 配列やListに対してNullかEmptyなのかを調べる
/// </summary>
public static bool IsNullOrEmpty<T>(this ICollection<T> collection)
{
    return collection == null || collection.Count == 0;
}
```

また、テンプレートのデータからクラスも生成できます。
Editor拡張でWindowを出すためのクラスをボタン一つで生成できます。毎回作るために調べていたので作成しました。

# ColorEyedropper

https://github.com/ayaha401/ColorEyedropper

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608797/1e0bd52f-3bf3-db6f-de9c-38fb243ec1da.png)

これはただのColorのListに色を保存できるだけのWindowです。
マテリアルのパラメータを少し動かして『あれ？色変わったか？』となることが多いのでこれを使用してスポイトで数値を保存して見比べます。

# DirectionalLightRotate

https://github.com/ayaha401/DirectionalLightRotate

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608797/485569ad-e39d-b791-ed4e-341d33f83c68.png)

UniversalAdditionalLightData(既存で存在するクラス)に時間を設定して回転する機能を追加します。

キャラのマテリアルを調整し、特定の時刻でどのような見た目になるのかチェックしたい！といったときに使えます。

ワンクリックで特定の時間の太陽の向きに調整できるので便利です。

# おわりに
以上がUnityで作業するために作った自作のEditor拡張たちです。
8割ぐらいが今年に作成しているはずです。
一度一生懸命書いたコードを忘れてしまったり、もう一度書くために思い出す時間を省略するために作っているのでEditor拡張はどんどん増えていく気がしています。