CustomEditor lazy template

開發 Unity3D 時, 是否經常在訂製 Editor, 希望為其中某些 SerializedProperty 部分做自訂, 但因為一開始訂製又需要整個 component 上的所有顯示的參數也需要訂製而覺得頭痛??!

其實如果簡單的取代某幾個 property 的繪製是可行的,
只需要以下的寫法即可.

public override void OnInspectorGUI()
{
	serializedObject.Update();
	SerializedProperty iter = serializedObject.GetIterator();
	iter.NextVisible(true); // enter children.
	
	EditorGUI.BeginChangeCheck(); // ---- change check [optional]
	do
	{
		// draw element & it's children
		EditorGUILayout.PropertyField(iter, includeChildren: true);
	}
	while (iter.NextVisible(false));
	if (EditorGUI.EndChangeCheck()) // ---- change check [optional]
		serializedObject.ApplyModifiedProperties();
}

這一段的寫法其實跟原本的

base.OnInspectorGUI();

就結果上完全沒有分別… 那麼為甚麼要這樣寫呢?!
原因

  • 可以保留在 Class 中宣告參數的順序
  • 可以保留一些特殊 attribute 如 [Header] [Range] 等這些繪製宣告
  • 可以單獨的對某個 property 進行額外加插的自訂方式 (後文述)
  • 可擴充性彈性, 基類的參數中, 沒有被指定的可以隨意增減修改, 而不需要重寫 Editor.

這裡提供一些變體用法, 跟 OnEnable 配搭可以輕易的取得當下繪製的 property, 是否自己希望修改的一員, 而作出相對應的取代.

SerializedProperty propA, propB;
private void OnEnable()
{
	propA = serializedObject.FindProperty("m_A");
	propB = serializedObject.FindProperty("m_B");
}

public override void OnInspectorGUI()
{
	serializedObject.Update();
	SerializedProperty iter = serializedObject.GetIterator();
	iter.NextVisible(true); // enter children.
	
	EditorGUI.BeginChangeCheck(); // ---- change check [optional]
	do
	{
		if (iter.propertyPath == propA.propertyPath)
		{
			// Special setup for A
			// if (Application.isPlaying) {...} else {....}
		}
		else if (iter.propertyPath == propB.propertyPath)
		{
			// Special setup for B
			EditorGUILayout.PropertyField(iter, includeChildren: true);
			EditorGUILayout.HelpBox("more info !!!", MessageType.Info);
		}
		else
		{
			// draw element & it's children
			EditorGUILayout.PropertyField(iter, includeChildren: true);
		}
	}
	while (iter.NextVisible(false));
	if (EditorGUI.EndChangeCheck()) // ---- change check [optional]
		serializedObject.ApplyModifiedProperties();
}

 

期待有更多的玩法, 歡迎討論.

,

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *

*