using System; using System.Collections.Generic; using System.Reflection; using UnityEngine; namespace Unity.VisualScripting { public class AnnotationUtility { static AnnotationUtility() { try { AnnotationUtilityType = Assembly.GetAssembly(typeof(UnityEditor.Editor)).GetType("UnityEditor.AnnotationUtility", true); AnnotationUtility_GetAnnotations = AnnotationUtilityType.GetMethod("GetAnnotations", BindingFlags.Static | BindingFlags.NonPublic); AnnotationUtility_SetGizmoEnabled = AnnotationUtilityType.GetMethod("SetGizmoEnabled", BindingFlags.Static | BindingFlags.NonPublic); AnnotationUtility_SetIconEnabled = AnnotationUtilityType.GetMethod("SetIconEnabled", BindingFlags.Static | BindingFlags.NonPublic); if (AnnotationUtility_GetAnnotations == null) { throw new MissingMemberException(AnnotationUtilityType.FullName, "GetAnnotations"); } if (AnnotationUtility_SetGizmoEnabled == null) { throw new MissingMemberException(AnnotationUtilityType.FullName, "SetGizmoEnabled"); } if (AnnotationUtility_SetIconEnabled == null) { throw new MissingMemberException(AnnotationUtilityType.FullName, "SetIconEnabled"); } AnnotationType = Assembly.GetAssembly(typeof(UnityEditor.Editor)).GetType("UnityEditor.Annotation", true); Annotation_classID = AnnotationType.GetField("classID", BindingFlags.Public | BindingFlags.Instance); Annotation_scriptClass = AnnotationType.GetField("scriptClass", BindingFlags.Public | BindingFlags.Instance); Annotation_iconEnabled = AnnotationType.GetField("iconEnabled", BindingFlags.Public | BindingFlags.Instance); Annotation_gizmoEnabled = AnnotationType.GetField("gizmoEnabled", BindingFlags.Public | BindingFlags.Instance); if (Annotation_classID == null) { throw new MissingMemberException(AnnotationType.FullName, "classID"); } if (Annotation_scriptClass == null) { throw new MissingMemberException(AnnotationType.FullName, "scriptClass"); } if (Annotation_iconEnabled == null) { throw new MissingMemberException(AnnotationType.FullName, "iconEnabled"); } if (Annotation_gizmoEnabled == null) { throw new MissingMemberException(AnnotationType.FullName, "gizmoEnabled"); } unityAnnotations = new Dictionary(); scriptAnnotations = new Dictionary(); var rawAnnotations = (Array)AnnotationUtility_GetAnnotations.Invoke(null, null); foreach (var rawAnnotation in rawAnnotations) { var annotation = new Annotation(rawAnnotation); if (annotation.classID == EditorUnityObjectUtility.MonoBehaviourClassID) { // Can happen when multiple types have the same name if (!scriptAnnotations.ContainsKey(annotation.scriptClass)) { scriptAnnotations.Add(annotation.scriptClass, annotation); } } else { unityAnnotations.Add(annotation.classID, annotation); } } } catch (Exception ex) { throw new UnityEditorInternalException(ex); } } private static readonly Type AnnotationUtilityType; private static readonly MethodInfo AnnotationUtility_GetAnnotations; private static readonly MethodInfo AnnotationUtility_SetGizmoEnabled; private static readonly MethodInfo AnnotationUtility_SetIconEnabled; private static readonly Type AnnotationType; private static readonly FieldInfo Annotation_classID; private static readonly FieldInfo Annotation_scriptClass; private static readonly FieldInfo Annotation_iconEnabled; private static readonly FieldInfo Annotation_gizmoEnabled; private static readonly Dictionary unityAnnotations; private static readonly Dictionary scriptAnnotations; public static Annotation GetAnnotation(Type type) { if (typeof(MonoBehaviour).IsAssignableFrom(type)) { var scriptClass = EditorUnityObjectUtility.GetScriptClass(type); if (!scriptAnnotations.ContainsKey(scriptClass)) { return null; } return scriptAnnotations[scriptClass]; } else { var classId = EditorUnityObjectUtility.GetClassID(type); if (!unityAnnotations.ContainsKey(classId)) { return null; } return unityAnnotations[classId]; } } public static Annotation GetAnnotation() { return GetAnnotation(typeof(T)); } public class Annotation { public Annotation(object instance) { this.instance = instance; classID = (int)Annotation_classID.GetValue(instance); scriptClass = (string)Annotation_scriptClass.GetValue(instance); } private readonly object instance; public int classID { get; private set; } public string scriptClass { get; private set; } public bool iconEnabled { get { try { return (bool)Annotation_iconEnabled.GetValue(instance); } catch (Exception ex) { throw new UnityEditorInternalException(ex); } } set { try { AnnotationUtility_SetIconEnabled.Invoke(null, new object[] { classID, scriptClass, value ? 1 : 0 }); } catch (Exception ex) { throw new UnityEditorInternalException(ex); } } } public bool gizmoEnabled { get { try { return (bool)Annotation_gizmoEnabled.GetValue(instance); } catch (Exception ex) { throw new UnityEditorInternalException(ex); } } set { try { if (EditorApplicationUtility.unityVersion.major >= 2019) { AnnotationUtility_SetGizmoEnabled.Invoke(null, new object[] { classID, scriptClass, value ? 1 : 0, false }); } else { AnnotationUtility_SetGizmoEnabled.Invoke(null, new object[] { classID, scriptClass, value ? 1 : 0 }); } } catch (Exception ex) { throw new UnityEditorInternalException(ex); } } } } } }