MEBIUSTOSのブログ

主にUnityに関する技術的な事を書いていきます。 Twitter @xflutexx

特定のギズモをオン・オフするエディタ拡張 | Unity

シーンビューにおいて特定のギズモの表示をオン・オフするエディタ拡張例です。指定したギズモのみを操作する例がネット上で見つからず、かつ自分で必要になったので作りました。

下記の例では実行する度にCapsuleColliderのオン・オフをトグル操作しています。(Unity5.2にて動作確認)

using UnityEngine;
using UnityEditor;
using System.Reflection;

public static class GizmoToggle {
    [MenuItem("Tools/GizmoToggle(CapsuleCollider)")]
    private static void Toggle() {
        // Annotation
        var annotationType = System.Type.GetType("UnityEditor.Annotation, UnityEditor");
        var classIdField = annotationType.GetField("classID");
        var scriptClassField = annotationType.GetField("scriptClass");
        var gizmoEnabledField = annotationType.GetField("gizmoEnabled");

        // AnnotationUtility
        var annotationUtilityType = System.Type.GetType("UnityEditor.AnnotationUtility, UnityEditor");
        var getAnnotationsMethod = annotationUtilityType.GetMethod("GetAnnotations", BindingFlags.NonPublic | BindingFlags.Static);
        var setGizmoEnabledMethod = annotationUtilityType.GetMethod("SetGizmoEnabled", BindingFlags.NonPublic | BindingFlags.Static);

        // BaseObjectTools
        var baseObjectToolsType = System.Type.GetType("UnityEditorInternal.BaseObjectTools, UnityEditor");
        var ClassIDToStringMethod = baseObjectToolsType.GetMethod("ClassIDToString", BindingFlags.Public | BindingFlags.Static);

        // 
        var annotations = getAnnotationsMethod.Invoke(null, null) as System.Array;
        foreach (var n in annotations) {
            // getClassName
            object[] parameters = new object[] {
                    (int)classIdField.GetValue(n)
                };
            var className = (string)ClassIDToStringMethod.Invoke(null, parameters);
            Debug.LogFormat("className: {0}", className);

            if (className == "CapsuleCollider") {
                // getGizmoEnable
                var gizmoEnabled = (int)gizmoEnabledField.GetValue(n);

                // toggle (0:off, 1:on)
                parameters = new object[] {
                    (int)classIdField.GetValue(n),
                    (string)scriptClassField.GetValue(n),
                    gizmoEnabled == 1 ? 0 : 1
                };
                setGizmoEnabledMethod.Invoke(null, parameters);
            }
        }
    }
}

下記のUnityDecompiledソースがとても役に立ちました。