Unityでエディタを拡張してみた
エディタの拡張をしてやりたいことがあるわけではないけれど、簡単に拡張できるらしいので試してみた。
Unityのマニュアルにエディターウィンドウの拡張について書かれ例が載っている。
Example.cs
”Editor”という名前のフォルダー内にスクリプトがある必要があるそうなので、Assetsフォルダの下にEditorフォルダを作りそこにExampleという名前のC#Scriptを作ってみた。コードはサンプルからちょっと変更して日本語のメニュー、タイトル、ラベルを試してみた。EditorWindowクラスから派生する必要がある。開いたら余白が多いウィンドウになったのでmaxSize,minSizeを指定して小さくしてみた。
using UnityEngine;
using UnityEditor;
using System.Collections;
public class Example : EditorWindow
{
[MenuItem("独自のメニュー/独自のウィンドウ")]
public static void ShowWindow()
{
//既存のウィンドウのインスタンスを表示。ない場合は作成します。
EditorWindow.GetWindow(typeof(Example));
}
void OnGUI()
{
this.titleContent = new GUIContent("タイトル");
this.maxSize = new Vector2(200, 100);
this.minSize = new Vector2(200, 100);
// 実際のウィンドウのコードはここに書きます
GUILayout.Label("ラベル", EditorStyles.boldLabel);
}
}
MyWindow.cs
マニュアルには「詳しくは、EditorWindow (エディターウィンドウ)に関するページを参照してください。」と書かれている。サンプルをMyWindow.csにコピー&ペーストしてみた。
サンプルのコードを見ると、OnGUI()の中にEditorGUILayoutがたくさん出てくるので、マニュアルの検索窓でEditorGUILayoutを検索してみた。
いくつか関数の先のサンプルコードをMyWindow.csにコピー&ペーストして追加してみた。
#region 文字列 ~#endregionはVisual Studioで閉じたり開いたりできる。閉じたときは#region 文字列の文字列の所が表示される。
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEditor.AnimatedValues;
// https://docs.unity3d.com/ja/current/Manual/editor-EditorWindows.html
// https://docs.unity3d.com/ja/current/ScriptReference/EditorWindow.html
// https://docs.unity3d.com/ja/current/ScriptReference/EditorGUILayout.html
public class MyWindow : EditorWindow
{
#region EditorWindow
string myString = "Hello World";
bool groupEnabled;
bool myBool = true;
float myFloat = 1.23f;
#endregion
#region EditorGUILayout.BeginFadeGroup
AnimBool m_ShowExtraFields;
string m_String;
Color m_Color = Color.white;
int m_Number = 0;
#endregion
#region EditorGUILayout.BeginScrollView
Vector2 scrollPos;
string t = "This is a string inside a Scroll view!";
#endregion
#region EditorGUILayout.CurveField
AnimationCurve curveX = AnimationCurve.Linear(0, 0, 10, 10);
AnimationCurve curveY = AnimationCurve.Linear(0, 0, 10, 10);
AnimationCurve curveZ = AnimationCurve.Linear(0, 0, 10, 10);
#endregion
// Window メニューに "My Window" というメニュー項目を追加
[MenuItem("Window/My Window")]
public static void ShowWindow()
{
//既存のウィンドウのインスタンスを表示。ない場合は作成します。
EditorWindow.GetWindow(typeof(MyWindow));
}
#region EditorGUILayout.BeginFadeGroup
void OnEnable()
{
m_ShowExtraFields = new AnimBool(true);
m_ShowExtraFields.valueChanged.AddListener(Repaint);
}
#endregion
void OnGUI()
{
#region EditorWindow
GUILayout.Label("Base Settings", EditorStyles.boldLabel);
myString = EditorGUILayout.TextField("Text Field", myString);
groupEnabled = EditorGUILayout.BeginToggleGroup("Optional Settings", groupEnabled);
myBool = EditorGUILayout.Toggle("Toggle", myBool);
myFloat = EditorGUILayout.Slider("Slider", myFloat, -3, 3);
EditorGUILayout.EndToggleGroup();
#endregion
#region EditorGUILayout.BeginFadeGroup
// EditorGUILayout.BeginFadeGroup
m_ShowExtraFields.target = EditorGUILayout.ToggleLeft("Show extra fields", m_ShowExtraFields.target);
//Extra block that can be toggled on and off.
if (EditorGUILayout.BeginFadeGroup(m_ShowExtraFields.faded))
{
EditorGUI.indentLevel++;
EditorGUILayout.PrefixLabel("Color");
m_Color = EditorGUILayout.ColorField(m_Color);
EditorGUILayout.PrefixLabel("Text");
m_String = EditorGUILayout.TextField(m_String);
EditorGUILayout.PrefixLabel("Number");
m_Number = EditorGUILayout.IntSlider(m_Number, 0, 10);
EditorGUI.indentLevel--;
}
#endregion
#region EditorGUILayout.BeginHorizontal
EditorGUILayout.EndFadeGroup();
Rect r = EditorGUILayout.BeginHorizontal("Button");
if (GUI.Button(r, GUIContent.none))
Debug.Log("Go here");
GUILayout.Label("I'm inside the button");
GUILayout.Label("So am I");
EditorGUILayout.EndHorizontal();
#endregion
#region EditorGUILayout.BeginScrollView
EditorGUILayout.BeginHorizontal();
scrollPos =
EditorGUILayout.BeginScrollView(scrollPos, GUILayout.Width(100), GUILayout.Height(100));
GUILayout.Label(t);
EditorGUILayout.EndScrollView();
if (GUILayout.Button("Add More Text", GUILayout.Width(100), GUILayout.Height(100)))
t += " \nAnd this is more text!";
EditorGUILayout.EndHorizontal();
if (GUILayout.Button("Clear"))
t = "";
#endregion
#region EditorGUILayout.CurveField
curveX = EditorGUILayout.CurveField("Animation on X", curveX);
curveY = EditorGUILayout.CurveField("Animation on Y", curveY);
curveZ = EditorGUILayout.CurveField("Animation on Z", curveZ);
if (GUILayout.Button("Generate Curve"))
AddCurveToSelectedGameObject();
#endregion
}
#region EditorGUILayout.CurveField
void AddCurveToSelectedGameObject()
{
if (Selection.activeGameObject)
{
FollowAnimationCurve comp =
Selection.activeGameObject.AddComponent<FollowAnimationCurve>();
comp.SetCurves(curveX, curveY, curveZ);
}
else
{
Debug.LogError("No Game Object selected for adding an animation curve");
}
}
#endregion
}
#region EditorGUILayout.CurveField
public class FollowAnimationCurve : MonoBehaviour
{
public AnimationCurve curveX;
public AnimationCurve curveY;
public AnimationCurve curveZ;
public void SetCurves(AnimationCurve xC, AnimationCurve yC, AnimationCurve zC)
{
curveX = xC;
curveY = yC;
curveZ = zC;
}
void Update()
{
transform.position = new Vector3(curveX.Evaluate(Time.time), curveY.Evaluate(Time.time), curveZ.Evaluate(Time.time));
}
}
#endregion
簡単に拡張できることがわかった。
EditorGUILayoutは将来削除される可能性がある
EditorGUILayoutのVersionが2019.4になっていたので、2021.1にしたらページがないと言われた。
検索したときにもうひとつEditorGUILayoutというタイトル名のページがあった。
Experimental: this API is experimental and might be changed or removed in the future.
https://docs.unity3d.com/ja/current/ScriptReference/Experimental.Networking.PlayerConnection.EditorGUILayout.html
将来は無くなってしまうのだろうか…