UnityのInspector拡張を行う際にはCustomEditorを利用するが
Unityのデフォルト型 (Transform や RectTransform等) の機能を残しつつ拡張する場合は
同じ処理を書く必要が出てくるそのため、以下のようなabstractを作成するといくらか拡張がマシになる
using UnityEditorInternal; using UnityEngine; namespace UnityEditor { public abstract class InternalEditorExtensionAbstract<T> : Editor where T : Component { private Editor _editor; protected T targetComponent; protected abstract string GetTypeName(); private void OnEnable() { var type = typeof(EditorApplication).Assembly.GetType(GetTypeName()); targetComponent = target as T; _editor = CreateEditor(targetComponent, type); Enable(); } private void OnDisable() { DestroyImmediate(_editor); Disable(); } public sealed override void OnInspectorGUI() { _editor.OnInspectorGUI(); } } }
例えば Transform の拡張をしたい場合は下記のように記述することでグローバルパラメータを見ることができる
using UnityEngine; namespace UnityEditor { [CustomEditor(typeof(Transform))] public class InspectorExtensionTransform : InternalEditorExtensionAbstract<Transform> { protected override string GetTypeName() { return "UnityEditor.TransformInspector"; } protected override void InspectorGUI() { using (new EditorGUI.DisabledScope(true)) { EditorGUILayout.LabelField("World (Read Only)"); EditorGUILayout.Vector3Field("Position", targetComponent.position); EditorGUILayout.Vector3Field("Rotation", targetComponent.rotation.eulerAngles); EditorGUILayout.Vector3Field("Scale", targetComponent.lossyScale); } } } }
問題点
CanEditMultipleObjects
CanEditMultipleObjects を利用した際にInspectorの表示が - にならず複数の値を操作することができない
そのため
using (var check = new EditorGUI.ChangeCheckScope()) { _editor.OnInspectorGUI(); if (check.changed && targets.Length > 1) { ComponentUtility.CopyComponent(targetComponent); foreach (var o in targets) ComponentUtility.PasteComponentValues(o as T); } }
のような処理を入れると適応されるが、すべてのパラメータを更新してしまうため意図しない挙動になってしまう
そして、もとと同じような実装をしようとしても、internalクラスが利用されているため、結局できないことが多い
特定のコンポーネントを上書きができない
私の知る範囲だとUnityEngine.UI.Imageのみであるが CustomEditor(typeof(Image)) をしても上書きできない
調べても理由は分からなかった
また、 UnityEngine.SpriteRenderer の Color プロパティも CustomPropery(typeof(Color)) で上書くことができない
内部を見たところPropertyFieldを使っているため、できそうな気がするが無理だった