Editor拡張 - ScriptableWizardについて

## 導入
[Editor拡張 - Windowを作ろう](https://qiita.com/iichin_tky/items/f24fa0464563c1a48da2)
で、Windowの作り方について取り上げました。

こちらを使えば基本的に何でも作れますが、ある作業に特化したWindowもあります。

それがScriptableWizard。
こちらはEditorWindowを継承して作られている事からも、何かに特化したWindowというのも頷けます。

## ScriptableWizardの特徴
何かを作る時に使用するウインドウです。

・GameObjectを作る
・Prefabを作る
・データアセットを作る
など。

## ScriptableWizardの作り方
1~2の手順は[Editor拡張 - Windowを作ろう](https://sge.qiita.com/iida_takuya/items/4915aafe2b2f29f093aa)編でも記載した手順通りなので説明は割愛します。

### 1. 継承したクラスを作る

まずは継承したクラスを作ります。
勿論スクリプトはEditorフォルダ以下に入れること。

```
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class SampleScriptableWizard : ScriptableWizard {
}
```

### 2. 開くトリガーを追加する
MenuItemを使ってヘッダーにメニューを追加します。

```
/// <summary>
/// スクリプタブルWizardをOpenする
/// </summary>
[MenuItem("Window/Scriptable Wizard Window")]
private static void Open()
{
}
```

### 3. ScriptableWizardを表示する
```
/// <summary>
/// スクリプタブルWizardをOpenする
/// </summary>
[MenuItem("Window/Scriptable Wizard Window")]
private static void Open()
{
	DisplayWizard<SampleScriptableWizard>("Sample Window");
}
```

ここまでのコードを実行すると、以下のようなWindowが作成されます。
標準で何かを作るための「Create」ボタンが作成されているようです。
<img width="315" alt="1.png" src="https://qiita-image-store.s3.amazonaws.com/0/35666/f57a3db6-6bff-492f-da22-3fa801c4c4cd.png">


### 4. パラメータの入力を受け付ける
[Editor拡張 - SeriazliedObjectに迫る](https://qiita.com/iichin_tky/items/85f878453639352d7667)
に対応する変数を定義すれば表示されます。

次のような変数を定義してみました。
復習がてら、どうWindowに表示されるかイメージしてください。

```
#region variable

public int Test1;

protected string Test2;

private float Text3;

[SerializeField]
private Camera Test4;

[SerializeField, HideInInspector]
private GameObject Test5;

[HideInInspector]
public RenderTexture Test6;

#endregion
```

正解はこうです。
<img width="318" alt="2983155e-ff60-cf52-6eb9-ddfef82f002b.png" src="https://qiita-image-store.s3.amazonaws.com/0/35666/141683c7-1f32-ed1c-d6b3-dbf5500caef6.png">


### 5. コールバックされる関数に内容を記述する
**OnWizardCreate関数**が「Create」ボタンを押した時にコールバックとして呼ばれます

```
/// <summary>
/// Createボタンが押された
/// </summary>
private void OnWizardCreate()
{
	// ここでデータアセットを自動生成したり、色々な操作を記述する
	new GameObject("Sample GameObject");
}
```

以上がScriptableWizardでの一連の作業フローです。

## その他
### DisplayWizard関数の引数について
DisplayWizardは引数を3つまで取ることが出来ます

```
/// <summary>
/// スクリプタブルWizardをOpenする
/// </summary>
[MenuItem("Window/Scriptable Wizard Window")]
private static void Open()
{
		DisplayWizard<SampleScriptableWizard>("Sample Window", "Create Button Name", "Other Button");
}
```

第二引数: Createボタンの名称変更
第三引数: もう1つボタンを加え、そのボタンの名称

このようになります。
<img width="316" alt="3.png" src="https://qiita-image-store.s3.amazonaws.com/0/35666/f450b510-c170-e815-ff38-3052bf7f0989.png">


### もう1つのボタンのコールバック
Createボタンと同様に以下のように追加します。

```
/// <summary>
/// もう1つのボタンが押された
/// </summary>
private void OnWizardOtherButton()
{
	Debug.Log("Pushed");
}
```


### OnWizardUpdate
全ての変数の値を対象に、値の変更があった場合に呼びだされるようです。

```
/// <summary>
/// 値の変更通知
/// </summary>
private void OnWizardUpdate()
{
	Debug.Log("Update");
}
```

### DrawWizardGUI
ウィザード内のGUIを描画するためのメソッドです。
このメソッドをオーバーライドしてGUIをカスタマイズできます。
返り値はboolです。

```
True: OnWizardUpdateを呼び出す
False: OnWizardUpdateを呼ばない
```

```
/// <summary>
/// WizardのGUIを上書きする
/// </summary>
protected override bool DrawWizardGUI ()
{
	base.DrawWizardGUI();
	EditorGUILayout.LabelField ("専用のラベル");
	Test1 = EditorGUILayout.IntSlider(Test1, 0, 100);

	//false を返すことで OnWizardUpdate が呼び出されなくなる
	return true;
}
```

こんな感じになります。
<img width="320" alt="4.png" src="https://qiita-image-store.s3.amazonaws.com/0/35666/11845979-5296-328a-7384-c12813049e85.png">

## 注意点
### OnGUIメソッドについて
通常のEditor拡張ではOnGUIメソッドを用いて、Editorの表示を拡張していきますが、ScriptableWizardは使用してはいけません。
なぜならば、ScriptableWizard側でOnGUIメソッドを記述しているためです。
(使っても良いですが、それはただのEditorWindowを継承しているのと変わらないです)

その代わりにDrawWizardGUIメソッドを使用しましょう。

## まとめ
Editor側の変数を用いて、Windowに値を表示して、
中身をゴチャゴチャと記述するなどの簡単なWindowを作る時に便利そうです。