だいぶ複雑になるが EditorGUILayout.PropertyField
の includeChildren: true
を利用せずに
すべての SerializedProperty
を取得し描画していくこともできる。
NextVisible
を利用するのは変わらないが、SerializedPropertyType.Generic
の場合は中身を更にループさせている
SerializedPropertyType.Generic
の場合でも CustomPropertyDrawer
を利用している場合は、適切なUIを表示させるために PropertyField
を利用する。
用途
この処理は、自作Attributeを利用しているときに用いる
serializeobject
のフィールドのみに Attribute
を適応するのであればこちらを利用する必要はないが
フィールドのクラスのも適応させたい場合こちらの処理を利用する必要がある。
コード
SerializedProperty が CustomPropertyDrawer を持っているかどうかの
HasCustomPropertyDrawer はこちらの記事を参考にしてください
hacchi-man.hatenablog.com
private void DrawProperty(SerializedProperty property, bool isSkip = false) { var depth = -1; var iterator = property.Copy(); for (var enterChildren = true; iterator.NextVisible(enterChildren) || depth == -1; enterChildren = false) { if (depth != -1 && iterator.depth != depth) return; depth = iterator.depth; if (isSkip) continue; if ("m_Script" == iterator.propertyPath) { using (new EditorGUI.DisabledScope(true)) EditorGUILayout.PropertyField(iterator); continue; } if (iterator.propertyType != SerializedPropertyType.Generic) { EditorGUILayout.PropertyField(iterator); continue; } if (HasCustomPropertyDrawer(iterator)) { EditorGUILayout.PropertyField(iterator, true); continue; } EditorGUILayout.PropertyField(iterator, false); if (!iterator.isExpanded) continue; EditorGUI.indentLevel++; bool enabled = GUI.enabled; var indentLevel = EditorGUI.indentLevel; var num = indentLevel - iterator.depth; EditorGUI.indentLevel = iterator.depth + num; DrawProperty(iterator); GUI.enabled = enabled; EditorGUI.indentLevel = indentLevel; } }