/// <summary> /// Draws a hint next to a visible field in the Inspector. /// </summary> /// <param name="hint">The content of the hint</param> /// <param name="fieldPathInClass">The path of the field within the class</param> /// <param name="targetType">The type of the class that contains the field</param> public static void DrawHintNextToInspectorField(DynamicHintContent hint, string fieldPathInClass, Type targetType) { if (!EditorWindow.HasOpenInstances <InspectorWindow>()) { return; } EditorWindow.FocusWindowIfItsOpen <InspectorWindow>(); Rect rectOfObject = GetRectOfFieldInInspector(fieldPathInClass, targetType, out bool objectWasFound); if (!objectWasFound) { return; } AdaptRectToInspector(out Rect rectOfHint, GUIUtility.GUIToScreenPoint(new Vector2(rectOfObject.x, rectOfObject.y))); DrawHintAt(hint, rectOfHint); }
/// <summary> /// Draws a hint next to an object in the Hierarchy, if it exists and the Hierarchy is visible. /// </summary> /// <param name="hint">The content of the hint</param> /// <param name="objectInHierarchy">The object the hint will be drawn next to</param> public static void DrawHintNextToHierarchyObject(DynamicHintContent hint, GameObject objectInHierarchy) { if (!EditorWindow.HasOpenInstances <SceneHierarchyWindow>()) { return; } EditorWindow.FocusWindowIfItsOpen <SceneHierarchyWindow>(); Rect rectOfObject = GetRectOfObjectInHierarchy(objectInHierarchy, out bool objectWasFound); if (!objectWasFound) { return; } AdaptRectToHierarchy(out Rect rectOfHint, GUIUtility.GUIToScreenPoint(new Vector2(rectOfObject.x, rectOfObject.y)), rectOfObject); DrawHintAt(hint, rectOfHint); }
/// <summary> /// Draws a hint next to a visible asset in the Project Window. /// </summary> /// <param name="hint">The content of hint tooltip</param> /// <param name="objectToFind">The object the hint will be drawn next to</param> public static void DrawHintNextToProjectAsset(DynamicHintContent hint, UnityEngine.Object objectToFind) { if (!EditorWindow.HasOpenInstances <ProjectBrowser>()) { return; } EditorWindow.FocusWindowIfItsOpen <ProjectBrowser>(); Rect rectOfObject = GetRectOfObjectInProjectExplorer(objectToFind, out bool objectWasFound); if (!objectWasFound) { return; } AdaptRectToProjectWindow(out Rect rectOfHint, GUIUtility.GUIToScreenPoint(new Vector2(rectOfObject.x, rectOfObject.y))); DrawHintAt(hint, rectOfHint); }
/// <summary> /// Draws a hint at a specific position of the screen. /// </summary> /// <param name="hint">The content of the hint</param> /// <param name="rect">The rect where the hint will be drawn. The top-left corner of the hint will start at the X coordinate</param> public static void DrawHintAt(DynamicHintContent hint, Rect rect) { TooltipView.s_ForceExtensionOfNextDynamicHint = true; TooltipView.Show(hint.ToTooltipString(), rect); }
internal static void DrawHint(Rect hintTriggerRect, Vector2 mousePosition, AssetReference assetReference) { if (!hintTriggerRect.Contains(mousePosition) || !GUIClip.visibleRect.Contains(mousePosition)) { return; } string assetPath = AssetDatabase.GUIDToAssetPath(assetReference.guid); var assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath); if (assetType == null) //this means the object or its base script has been deleted and is "Missing" { return; } var hintGenerators = TypeCache.GetMethodsWithAttribute <DynamicHintGeneratorAttribute>(); if (assetType.IsSubclassOf(typeof(ScriptableObject))) { DynamicHintContent hint = GetDynamicHintContentOf(hintGenerators, assetType, assetPath); if (hint != null) { DrawMouseTooltip(hint, hintTriggerRect); } return; } if (assetType == typeof(GameObject)) { /* GameObjects can have multiple components with custom tooltips * so for now we'll just display the first one. * If needed, we could: * 1) Implement a "priority system" (like OrderedCallbacks) * 2) Display one big tooltip made up with all elements from custom tooltip */ GameObject assetGameObject = (GetLoadedObjectFromInstanceID(assetReference.instanceID) as GameObject); if (!assetGameObject) { /* this seems to happen non-deterministically at project startup depending of what the user is hovering when the editor opens, * or while the user is scrolling a list of objects and hovers one of them casually, even if the object hovered is actually a * GameObject. * */ return; } foreach (var component in assetGameObject.GetComponents <Component>()) { if (component == null) { continue; } //this means its script has been deleted and is "Missing" DynamicHintContent hint = GetDynamicHintContentOf(hintGenerators, component.GetType(), string.Empty, component); if (hint == null) { continue; } DrawMouseTooltip(hint, hintTriggerRect); return; } } }
/// <summary> /// Draws a hint at a Rect, if the mouse is in it. /// </summary> /// <param name="hint">The hint to draw</param> /// <param name="tooltipRect">The rect where the hint will be drawn</param> internal static void DrawMouseTooltip(DynamicHintContent hint, Rect tooltipRect) { GUIStyle.SetMouseTooltip(hint.ToTooltipString(), tooltipRect); }
internal static string Serialize(DynamicHintContent hint) { return($"[Custom Tooltip]<type>{hint.GetType().AssemblyQualifiedName}</type><content>{JsonUtility.ToJson(hint)}</content>"); }