Issue keeping button hover state when updating other elements on the screen

I keep running into issues where I’m animating one element on the screen during runtime, and it causes any buttons that the mouse is over to lose their hover state.

One example is that I have a progress bar that I want to fill up when a user holds down the mouse on a button.

   _progressBar.style.width = new StyleLength(new Length { value = progress, unit = LengthUnit.Percent });

But whenever I hold down the mouse button, the mouse leave event triggers directly after the progress bar is updated for the first time.

Is there a different way I should be updating elements?

1 Like

I have similar issue but with updating some data within the tree. It almost feels like that at some point the elements are temporarily hidden and shown (like a redraw within one frame), and this causes the hierarchy to change layout, and thus in fact the pointer is temporarily not “above” the element, causing an immediate Leave. I’m working on a repro project …

I did some more testing and it works fine if the update is in the same component, so it must be something to do with how I’m managing child components.

Edit: It looks like adding the “Input System Event System (UI Toolkit)” to the scene is what breaks it. I created a new game from scratch using the default URP package, added the com.unity.ui, com.unity.ui.builder, and com.unity.inputsystem

I then added the below scripts and added them to the scene. The button highlights in red when the event system is disabled, and then the highlight breaks as soon as the event system is re-enabled.

using UnityEngine;
using UnityEngine.UIElements;

public class WidthUpdater : MonoBehaviour
{
    [SerializeField] private float _loaderSpeed = 5f;

    private VisualElement _root;
    private VisualElement _loader;
    private float _loaderWidth = 0;

    public void OnEnable()
    {
        _root = GetComponent<UIDocument>().rootVisualElement;

        _loader = _root.Q<VisualElement>("Loader");
    }

    public void Update()
    {
        _loaderWidth += Time.deltaTime * _loaderSpeed;
        if (_loaderWidth > 100) _loaderWidth = 0;

        _loader.style.width = new StyleLength(new Length { value = _loaderWidth, unit = LengthUnit.Percent });
    }
}
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
    <Style src="SampleStylesheet.uss" />
    <ui:VisualElement>
        <ui:VisualElement name="Loader" style="background-color: rgb(255, 0, 0); height: 20px; width: 23%;" />
    </ui:VisualElement>
    <ui:VisualElement style="flex-grow: 1; align-items: center; justify-content: center;">
        <ui:Button text="Button" display-tooltip-when-elided="true" />
    </ui:VisualElement>
</ui:UXML>
Button:hover {
    background-color: rgb(152, 0, 0);
}

Button {
    width: 300px;
    height: 50px;
    background-color: rgb(33, 76, 142);
    font-size: 20px;
    -unity-font-style: bold;
    color: rgba(248, 248, 248, 255);
}

Hi SteveSync,

Thank you for reporting this problem. We are aware of (and working on a fix for) an issue with the hover state being instable in runtime whenever an element (not necessarily the one that’s hovered) moves or changes dimensions. That issue shouldn’t be influenced by the fact that you are using the new Input System with the InputSystemEventSystem component though. We also have a number of smaller fixes on the InputSystemEventSystem that are due in our next package update (preview 15) if all goes well, though the hover bug itself will probably not make it in that update just yet. With a bit of luck your problems should end up being fixed by these next updates, but I can’t really suggest a good workaround for you in the meantime…

For repro purposes on our side, what version of Unity are you using exactly?

Thanks for the reply! Good to know you’re on it. :slight_smile:

I was using 2021.1.3f1, and have got a small example project with a reproducable case in it, but now I’m back using 2020.3.6f1 since DOTS is not supporting 2021 :expressionless:

Do you know if the fix will be available for the 2020 versions of Unity?

Hi! Is there an issue tracker for this problem? I would like to stay tuned about that.

Thanks!

Here you go: https://issuetracker.unity3d.com/issues/hover-state-resets-when-there-is-another-ui-toolkit-element-in-the-same-uidocument-that-is-rotated-or-moved

1 Like

I have the same problem when ui elements are changed via script, for example when a progress bar changes it’s length.
And it doesn’t matter if I do this by updating the style (for example width), or by chaning the transform scale.

The bug is fixed it seams in preview16, but still present in Unity 2021.2.0.b8

@manuelgoellnitz
That’s also my impression, preview.15/preview.16 fixed this issue.

It seams the bug is not present in a 2021.2.0b8 windows build. Only in the editor.

1 Like

Thanks for pointing that out @manuelgoellnitz , I was spending a long time trying to figure out why I kept losing hover state on a parent element when I would press down on a child button and move the mouse slightly, but I went to test an actual build on Windows and it works fine there. Problem only exists in the editor in 2021.2