この記事はUnityのCustomEditor(カスタムエディター)を共有します。
Unity は、MonoBehavior スクリプトを継承するクラス (もちろん他のクラスもあります) のプロパティ パネルの表示と変更を提供します。
デフォルトでは、クラスのパブリック フィールドが表示されます。もちろん、これらのフィールドもシリアル化され、マウントされたプレハブに保存されます。
場合によっては、表示および変更ロジックをカスタマイズし、それを使用する必要がありますCustomEditor
。
この記事では、主に クラス のシリアル化可能なフィールドCustomEditor
を中心に、基本的な概要を説明します。
CustomEditor の基礎知識
以下では、まず比較的完全なコードを示し、次にその意味を 1 つずつ説明します。
// Assets/xxxx/MonoTestEditor.cs
public class MonoTest : MonoBehaviour
{
public enum EnumValue
{
EnumValue1,
EnumValue2,
EnumValue3,
}
public int intValue;
public bool boolValue;
public EnumValue enumValue;
}
// Assets/xxxx/Editor/MonoTestEditor.cs
[CustomEditor(typeof(MonoTest), true)]
public class MonoTestEditor : Editor
{
private MonoTest m_Target;
private SerializedProperty m_IntValue;
private SerializedProperty m_BoolValue;
private SerializedProperty m_EnumValue;
private void OnEnable()
{
_target = target as MonoTest;
m_IntValue = serializedObject.FindProperty("intValue");
m_BoolValue = serializedObject.FindProperty("boolValue");
m_EnumValue = serializedObject.FindProperty("enumValue");
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
serializedObject.Update();
//......//
serializedObject.ApplyModifiedProperties();
}
}
まず、カスタム Editor クラスを任意の Editor ディレクトリに配置する必要があります。
次に、[CustomEditor(typeof(MonoTest), true)]
属性を使用してカスタマイズするクラスを記述し、2 番目のパラメーターはそのサブクラスに影響を与えるかどうかを表します。
次に、親クラスからクラスを継承しますpublic class MonoTestEditor : Editor
。
CustomEditor
クラスには 2 つのキー属性がありtarget
、serializedObject
前者はカスタマイズするクラスのインスタンス化されたオブジェクトを表します。デフォルトはObject
型です。通常、それを OnEnable: の対応するクラスに変換します_target = target as MonoTest;
。serializedObject
属性は、対応するクラスのすべてのシリアル化されたフィールドをカプセル化します。また、いくつかの便利なメソッドでは、各フィールドがシリアル化されたプロパティに対応しSerializedProperty
、使用する前に 2 つをバインドしますm_IntValue = serializedObject.FindProperty("intValue");
。
次に、OnInspectorGUI
オブジェクトがフォーカスを取得したとき、オブジェクトのプロパティが変更されたとき、またはその他の場合に呼び出されるメソッドを書き換えます。base.OnInspectorGUI();
これは、シリアル化されたすべてのプロパティがエディターのデフォルトの動作に従って描画されることを意味します。他のコードはありません。プロパティ パネルはデフォルトの描画と一致します。この文を削除すると、スクリプトの名前だけがプロパティ パネルに描画されます。
次に、serializedObject
更新して変更を適用します: serializedObject.Update();
、serializedObject.ApplyModifiedProperties();
。
最後に、コードの 2 行の間に独自の表示をカスタマイズします。ちなみに、serializedObject.ApplyModifiedProperties()
can の戻り値は、シリアル化されたフィールドが変更されたかどうかを示します。
エディターのコアロジックをカスタマイズする
カスタム エディターの主な内容は、シリアル化されたフィールドの外観を定義し、フィールドが変更されたときに対応する操作を実行することです。
したがって、主に扱うべきことは と ですserializedObject
。serializedObject
もちろん、 などの外観を構築するさまざまなクラスがあります。この記事はカスタム エディターの基本的な紹介にすぎず、関連するクラスの詳細な紹介はGUI, GUILayout, EditorGUILayout
含まれません。GUI
シリアル化されたフィールドの外観を定義します
場合によっては、シリアル化されたフィールドの外観が単純すぎるため、より充実した表示が必要になることがあります。この場合、GUI
関連するインターフェイスを使用することで目的を達成できます。いくつかの例を以下に示します。
public override void OnInspectorGUI()
{
// base.OnInspectorGUI(); // 将默认的绘制关闭
serializedObject.Update();
// 使用基本的绘制
// EditorGUILayout.PropertyField(m_IntValue, new GUIContent("这是一个整型值的提示"));
// EditorGUILayout.PropertyField(m_BoolValue);
// EditorGUILayout.PropertyField(m_EnumValue);
var content = new GUIContent {text = "整型值", tooltip = "这是一个整型值的提示"};
EditorGUILayout.IntSlider(m_IntValue, 0, 100, content); // 使用一个滑动条来代替基本的绘制, 可以规定上下界, 可以修改相关提示
var curValue = m_BoolValue.boolValue;
m_BoolValue.boolValue = EditorGUILayout.Toggle("布尔值", m_BoolValue.boolValue);
if (m_BoolValue.boolValue != curValue)
Debug.LogError("value changed!" + m_BoolValue.boolValue); // 在值变化后进行一些操作
//m_BoolValue.boolValue = EditorGUILayout.Toggle("布尔值", m_BoolValue.boolValue);
// if (serializedObject.ApplyModifiedProperties())
// Debug.LogError("value changed!" + m_BoolValue.boolValue); // 在值变化后进行一些操作
m_EnumValue.intValue = (int)(MonoTest.EnumValue)EditorGUILayout.EnumPopup("enumValue", (MonoTest.EnumValue)m_EnumValue.intValue); // 使用自定义的枚举值
serializedObject.ApplyModifiedProperties();
}
を使用するEditorGUILayout.PropertyField(xxxx)
と、デフォルトの動作に従ってフィールドが描画されます。また、他のコントロールを使用して値を取得してフィールドに割り当てることも、m_BoolValue.boolValue = EditorGUILayout.Toggle("布尔值", m_BoolValue.boolValue);
バインドされたオブジェクトに値を直接割り当てることもできますが、この割り当ては手動で保存して変更するm_Target
必要があります。 prefab 上で実行されるため、通常はシリアル化されたオブジェクトを操作するための仲介手段としてこれを使用します。SerializedProperty
フィールドが変更されたときに何かを行う
永続フィールドの変更を検出し、変更があったときに対応する操作を実行する何らかの手段を用意できます。
1 つ目の方法は、次のように描画前に現在の値のコピーを保存し、描画割り当て後に 2 つの値を比較することです。
m_BoolValue.boolValue = EditorGUILayout.Toggle("布尔值", m_BoolValue.boolValue);
if (m_BoolValue.boolValue != curValue)
Debug.LogError("value changed!" + m_BoolValue.boolValue); // 在值变化后进行一些操作
2 番目の方法は、描画直後に各フィールドにアプリケーションを適用することですserializedObject.ApplyModifiedProperties();
。値が変更された場合、このメソッドの関数は次のtrue
ような を返します。
m_BoolValue.boolValue = EditorGUILayout.Toggle("布尔值", m_BoolValue.boolValue);
if (serializedObject.ApplyModifiedProperties())
Debug.LogError("value changed!" + m_BoolValue.boolValue); // 在值变化后进行一些操作
特定のフィールドの変更を禁止する
場合によっては、特定のフィールドの変更を禁止する必要があります。このとき、フィールドを描画する前後で GUI を切り替えるだけで済みます。たとえば、フィールドは非実行モードでのみ変更できます。
if (Application.isPlaying)
{
GUI.enabled = false;
m_BoolValue.boolValue = EditorGUILayout.Toggle("布尔值", m_BoolValue.boolValue);
GUI.enabled = true;
}
else
{
m_BoolValue.boolValue = EditorGUILayout.Toggle("布尔值", m_BoolValue.boolValue);
}
このように、描画されたフィールドは実行モードではグレー表示され、編集できないことが示されます。
要約する
この記事ではCustomEditor
、 について簡単に紹介し、考えられるいくつかの問題とヒントについて言及し、皆様のお役に立てれば幸いです。