Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Tooltips in UI Toolkit

Discussion in 'UI Toolkit' started by JHSV, Jun 15, 2020.

  1. JHSV

    JHSV

    Joined:
    Jul 11, 2013
    Posts:
    25
    What is the status on tooltips in UI Toolkit? I am using Unity 2019.4.0f1 and added a few tooltips by filling in the "Tooltip" field for an element in UI Builder. However, when I ran it, nothing happened when I moused over the element. Is other setup required, maybe styling perhaps? Or has it not yet been implemented?
     
  2. stan-osipov

    stan-osipov

    Unity Technologies

    Joined:
    Feb 24, 2020
    Posts:
    31
    Hello, no extra set up is required. The tooltip will appear if you will hover over the element for a few seconds. Can you explain what do you mean by
    Are you talking about the UI Builder Preview mode?

     
  3. JHSV

    JHSV

    Joined:
    Jul 11, 2013
    Posts:
    25
    I see the tooltip in UI Builder Preview mode, but when I go into the Unity Play mode or in a build, it does not show up.
     
  4. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,203
    Tooltips are only supported in the Editor at this time. You'll need a custom tooltip solution for runtime.
     
  5. JHSV

    JHSV

    Joined:
    Jul 11, 2013
    Posts:
    25
    Which UI Toolkit mechanisms would be involved in implementing a custom solution?
     
  6. Prodigga

    Prodigga

    Joined:
    Apr 13, 2011
    Posts:
    1,122
    Hopefully some method that allows us to use that tooltip field, otherwise we have this tooltip field that is only useful for editor UI, which seems a little gross!
     
    DragonCoder likes this.
  7. Digika

    Digika

    Joined:
    Jan 7, 2018
    Posts:
    225
    :hover and shadow child-elements with `display:none`
     
  8. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,203
    My recommendation is to create a VisualElement that you render last (is the last child of the rootVisualElement), and that you set to Absolute position plus left/right/top/bottom set to 0. This will make it take up the entire screen (entire rootVisualElement). Think of this as your "tooltip layer".

    You can then use a MouseManipulator that you attach to any elements that need a tooltip that monitors for MouseEnter/MouseLeave and when needed creates an the tooltip element as a child of the "tooltip layer", with Absolute positioning, and left/top properties set to the either the worldBounds of the target element or the mouse coordinates from the MouseEvents. ...Roughly speaking.
     
    ssd and DragonCoder like this.
  9. Digika

    Digika

    Joined:
    Jan 7, 2018
    Posts:
    225
    Any particular reason you recommend separate layer down the tree and put all tooltips objects (or even create it runtime every hover) instead of just having them pre-defined in the hierarchy and target with USS parent:hover > .tooltip for example?
     
  10. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,203
    So you can have a single tooltip element that you re-use as needed for the currently hovered element, instead of creating a tooltip element for _every_ element with a tooltip. But both are valid options. If you have crazy complex tooltips with very custom elements inside that are different between all your elements, then having a dedicated tooltip element per-element makes more sense.
     
    JustAnotherDude likes this.
  11. mrSaig

    mrSaig

    Joined:
    Jan 14, 2010
    Posts:
    68
  12. tankorsmash

    tankorsmash

    Joined:
    Jul 20, 2019
    Posts:
    7
    https://web.archive.org/web/2021032.../09/21/uitoolkit-runtime-tool-tips-made-easy/ mirror of mrSaigs page now that it's down, but here's the code included:

    > We just have to write a new manipulator and add it to the elements who needs tool tips.

    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.UIElements;
    6.  
    7. public class ToolTipManipulator : Manipulator
    8. {
    9.  
    10.     private VisualElement element;
    11.     public ToolTipManipulator()
    12.     {
    13.     }
    14.  
    15.     protected override void RegisterCallbacksOnTarget()
    16.     {
    17.         target.RegisterCallback<MouseEnterEvent>(MouseIn);
    18.         target.RegisterCallback<MouseOutEvent>(MouseOut);
    19.     }
    20.  
    21.     protected override void UnregisterCallbacksFromTarget()
    22.     {
    23.         target.UnregisterCallback<MouseEnterEvent>(MouseIn);
    24.         target.UnregisterCallback<MouseOutEvent>(MouseOut);
    25.     }
    26.  
    27.     private void MouseIn(MouseEnterEvent e)
    28.     {
    29.         if (element == null)
    30.         {
    31.             element = new VisualElement();
    32.             element.style.backgroundColor = Color.blue;
    33.             element.style.position = Position.Absolute;
    34.             element.style.left = this.target.worldBound.center.x;
    35.             element.style.top = this.target.worldBound.yMin;
    36.             var label = new Label(this.target.tooltip);
    37.             label.style.color = Color.white;
    38.  
    39.             element.Add(label);
    40.             var root = (VisualElement)UiHelper.FindRootElement(this.target);
    41.             root.Add(element);
    42.            
    43.         }
    44.         element.style.visibility = Visibility.Visible;
    45.         element.BringToFront();
    46.     }
    47.  
    48.     private void MouseOut(MouseOutEvent e)
    49.     {
    50.         element.style.visibility = Visibility.Hidden;
    51.     }
    52. }
    and

    > Just copy this code into ToolTipManipulator.cs in your Unity project and following code to things who need to have a tool tip.

    Code (CSharp):
    1. //Optional if icons tooltip was not set before in UiBuilder ...
    2. element.Q<VisualElement>("Icon").tooltip = "I am a tooltip";
    3.  
    4. element.Q<VisualElement>("Icon").AddManipulator(new ToolTipManipulator())
     
  13. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    1,221
    Thanks for sharing it, though, what is where is the UiHelper class? Was it a set of custom extension methods?


    Edit -----------------------
    Never mind about this, I was able to work out a solution. Minus the fact that on Linux, even this solution doesn't work right. Nothing seems to. : /

    No matter what, tooltip end up in the top left corner of whatever window they are a part of. Annoying and extremely unuseful as you can't really even notice it.

     
    Last edited: Jun 18, 2021
  14. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,146
    Ye, those editor tooltips are very broken. Even UI Builder have them showing up in wrong spots. But I guess they will have that fixed soon enough.

    I've update this repo with an example of how to do runtime tooltips in UI toolkit.
    https://github.com/plyoung/UIElements
     
    Last edited: Jun 21, 2021
    Sevaron01, monark, Arlorean and 6 others like this.
  15. stevenmare

    stevenmare

    Joined:
    Jul 20, 2018
    Posts:
    76
    I cannot find the UiHelper class. Is that still a thing?
    Is there another way to get the root element of the Manipulator's target?
    Currently I'm sending the root through as a field in the constructor but that probably not the best way to do it.
     
  16. yukunlinykl

    yukunlinykl

    Joined:
    Dec 17, 2021
    Posts:
    21
    This is my solution without add Manipulator for all visualelement:
    The key point is use "panel.Pick(RuntimePanelUtils.ScreenToPanel(panel, screenPosition))" to get which visual element the mouse is hover on.

    reference: https://docs.unity3d.com/2022.2/Documentation/Manual/UIE-faq-event-and-input-system.html

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.EventSystems;
    3. using UnityEngine.UIElements;
    4.  
    5. public class ToolTipHelper : MonoBehaviour
    6. {
    7.     private VisualElement root;
    8.     private Label label;
    9.  
    10.     void Start()
    11.     {
    12.         root = GetComponent<UIDocument>().rootVisualElement;
    13.         label = root.Q<Label>();
    14.     }
    15.  
    16.     void Update()
    17.     {
    18.         string tooltip = CurrentToolTip(root.panel);
    19.         if (tooltip != "")
    20.         {
    21.             label.visible = true;
    22.             label.text = tooltip;
    23.             label.style.left = Input.mousePosition.x + 15;
    24.             label.style.top = Screen.height - Input.mousePosition.y;
    25.         }
    26.         else
    27.         {
    28.             label.visible = false;
    29.         }
    30.     }
    31.  
    32.     string CurrentToolTip(IPanel panel)
    33.     {
    34.         // https://docs.unity3d.com/2022.2/Documentation/Manual/UIE-faq-event-and-input-system.html
    35.  
    36.         if (!EventSystem.current.IsPointerOverGameObject()) return "";
    37.  
    38.         var screenPosition = Input.mousePosition;
    39.         screenPosition.y = Screen.height - screenPosition.y;
    40.  
    41.         VisualElement ve = panel.Pick(RuntimePanelUtils.ScreenToPanel(panel, screenPosition));
    42.         return ve == null ? "" : ve.tooltip;
    43.     }
    44. }
    45.  
     
    UniqueCode likes this.