Unityのエディター拡張

エディター拡張をしてみたんでMEMO


少し手の込んだことをしてみました。
  • ScriptableObjectを使ったアセットを自分で作った
  • アセットを自動で生成
  • ディレクトリやファイルを自動で作成
  • ScriptableObjectのインスペクタ―ウィンドウを変える
  • 一日分時間が潰れた!

少しめちゃくちゃ遠回りをしてしまったように思います。


参考になるサイト

エディタ拡張入門

 


エディタ拡張をしたら、インスペクターからプロパティを変更した後、一度ユニティを終了して、データが保存されているか確認した方が良いと思います。

目的:会話イベントを作りやすいようにしたかった

 

とりあえず:
Assetを自分でつくる。

ScriptableObjectを継承したクラスはSerialize(直列化)可能になり、Unityの普通のアセットと同じようにインスペクタ―から編集できます。

[Serializable]
[CreateAssetMenu(menuName ="makeAsset")]
public class TargetClass : ScriptableObject {

[SerializeField]
public string msg;
[SerializeField]
public int no;
}

こんな感じですれば、

こういうふうにAssetが作れます。

ちなみに、

コンポーネントとして作っても(MonoBehaviourを継承したクラスでも)、アセットでも(ScriptableObjectを継承したクラスでも)、画像のようにアイコンを変えることがインスペクタ―から可能です。

アイコンが、こんなかんじになります。

これで簡単なアセットを作れた。


インスペクタ―の画面を変える

クラスを作ります。

エディタ拡張するクラスはUnityEditor.Editorを継承する。

クラス宣言をするときに以下の属性をつける。

[CustomEditor(typeof(TargetClass))]
[CanEditMultipleObjects]
//↑の属性をクラスの前につける
public class TargetClassEditor : UnityEditor.Editor {

private void OnEnable()
{

}
public override void OnInspectorGUI()
{
    base.OnInspectorGUI();
}
}

作るクラス名はエディタ拡張したいクラス名+Editorにすると公式のリファレンスに書いてありました。別に書かなくても動いたけど。

 

それと、

Editorクラスを継承したクラスはEditorフォルダ以下に置く必要があります。

適当なフォルダに置いておくと、

Instance of TargetClassEditor couldn’t be created. The script class needs to derive from ScriptableObject and be placed in the Assets/Editor folder.

という例外が発生するはずです。というか僕は出ました。

 

 

そして、これに処理を書き込んでいくことで、エディタからインスペクタ―を開いた時の動作を自分で設定できます。

ためしに、OnInspectorGUI()内のbase.OnInspectorGUI();を消すとインスペクタ―に何も表示されなくなります。反映されていることがわかります。


まあここまでは、良かったんですが、ここから先でつまりました。

画面がうまく変わらなかったりフォルダやファイルを作れなかったり

一番てこずったのが、ファイルがちゃんと保存されないことでした。

ぼちぼち、必要になったとこだけ、書いていきます。


GUIレイアウト

横に並べたいとか、縦に並べたいとか、枠をつくりたいとか。

テンプレートみたいなものが、Unityで用意されているのでそれについて。

割と簡単だったりします。

public override void OnInspectorGUI()
{
 base.OnInspectorGUI();
 
 GUILayout.BeginHorizontal(GUI.skin.box);
 //このレイアウトは横並びになる
 GUILayout.Label("テスト");
 GUILayout.Label("テスト");
 GUILayout.EndHorizontal();

 GUILayout.BeginVertical();
 //このレイアウトは縦並びになる
 GUILayout.Label("たて");
 GUILayout.Label("たて");
 GUILayout.EndVertical();
}

こんな表示になる。


インプットフィールド

一番、重要な部分ですが、入力するフィールドについてです。

入力された値を、自分で作ったアセット(ScriptableObject)にいれる。

[CustomEditor(typeof(TargetClass))]
[CanEditMultipleObjects]
public class TargetClassEditor : UnityEditor.Editor {
  SerializedProperty propaty;
private void OnEnable()
{
 propaty = serializedObject.FindProperty("sprite");
}
public override void OnInspectorGUI()
{
 base.OnInspectorGUI();
 EditorGUILayout.PropertyField(propaty);
 serializedObject.ApplyModifiedProperties();
}

こんな感じですれば、勝手にフィールドが作られます。

EditorGUILayout.PropertyFieldとGUILayoutの枠を作るメソッドさえ使えば大体まかなえそう。

便利。

serializedObject.ApplyModifiedProperties();を最後につけとかないと、この変えた情報が他から参照するときに、反映されなかったりするかも。

 

公式のスクリプトリファレンスも参考になります。

この辺で一旦きります。

続く

コメント

タイトルとURLをコピーしました