OnPointerExit not always firing?

I’m trying to make a tooltip. Currently I have a few buttons next to one another which should get highlighted in the OnPointerEnter function, and of course, stop highlighting in the OnPointerExit function.

For the most on this works fine, however, these buttons are rather close to one another, let’s call them “Attack” and “Defend”, if I move my mouse slowly from “Attack” to “Defend” my tooltip changes accordingly. However when I quickly move my mouse from “Attack” to “Defend” it will keep showing “Attack” as if the update for onPointerExit was never called in the small gap there is between them, if the mouse moves fast enough.

I have a similar setup with GameObjects using OnMouseOver that works completely fine, but with these UI elements I can’t make it work properly.

Here’s my code:

public class TooltipManager : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
    GameObject currentHover;

    void Update()
    {
        if (currentHover)
        {
            Debug.Log(currentHover.name + " @ " + Input.mousePosition);        
        }
    }

    public void OnPointerEnter(PointerEventData eventData)
    {
        if (eventData.pointerCurrentRaycast.gameObject != null)
        {
            Debug.Log("Mouse Over: " + eventData.pointerCurrentRaycast.gameObject.name);
            currentHover = eventData.pointerCurrentRaycast.gameObject;
            Tooltip.ShowTooltip(currentHover.name);
        }
    }



    public void OnPointerExit(PointerEventData eventData)
    {
        Debug.Log("Exit hover");
        currentHover = null;
        Tooltip.HideTooltip();
    }
}

Hello,
Did you find a workaround ? I got the same problem.

2 Likes

Unfortunately not, this is still on my bug list to-be-fixed :frowning:
I’ll definitely update this thread if I ever find a workaround.
I suppose using gameobjects instead would work, but it’s such a dirty solution I’d rather not do so

I faced the Same problem now

1 Like

I fixed my problem. I problem is that I used OnPointerExit/OnPointerEnter to show/Display the Tooltip on my game. When I Hover this Item, The ToolTips always blink(one Display one Hide many times in one second). I used one hour to search for the answer. FInally, I found one solution I did not need to change the Interface even code. I only need to change the pivot point of my Tooltips in my game(One UI IMAGE GameObject). Here is my code.

[This is my solution so that might be not targeted for your situation, But I really face the same situation And search and found your Post]

Call this Function inside Update

private void UpdateTooltip()
    {
        Vector2 pos;
        //RectTransformUtility.ScreenPointToLocalPointInRectangle(GameObject.Find("Menu Canvas").transform.GetChild(0).transform.GetChild(2).transform as RectTransform, Input.mousePosition, null, out pos);
        RectTransformUtility.ScreenPointToLocalPointInRectangle(GameObject.Find("Menu Canvas").transform as RectTransform, Input.mousePosition, null, out pos);

        if (isShow)
        {
            tooltip.ShowTooltip();
            tooltip.SetLocationPosition(pos);
        }
        else
        {
            tooltip.HideTooltip();
            tooltip.SetLocationPosition(pos);
        }
    }

#region Observer Pattern
    private void OnEnter()
    {
        //Debug.Log("OB ENTER");
        isShow = true;
    }

    private void OnExit()
    {
        //Debug.Log("OB EXIT");
        isShow = false;
    }

1 Like

And This is my ItemButton Code

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System;

public class ItemButton : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IBeginDragHandler, IDragHandler, IEndDragHandler
{
    public int buttonID;
    public Image itemButtonImage;
    [HideInInspector] public Text itemNumberText;

    #region Observer Pattern
    public static Action onEnter;
    public static Action onExit;
    public static Action OnLeftBeginDrag;
    public static Action OnLeftDrag;
    public static Action OnLeftEndDrag;
    #endregion


    private void Start()
    {
        itemNumberText = GetComponentInChildren<Text>();
    }

    //TODO Mouse Hover Later & Add TARGET Image hit OR BG Color change
    //MARKER When you press the ItemBUTTON, You will CALL thie FUNCTION
    public void PressItemButton()
    {
        if(GameManager.instance.itemsHeld[buttonID] != "")
        {
            GameMenu.instance.SelectItem(GameManager.instance.GetItemDetail(GameManager.instance.itemsHeld[buttonID]));
        }
    }


    #region event
    public void OnPointerEnter(PointerEventData eventData)
    {
        if (onEnter != null)
        {
            onEnter();
        }
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        if (onExit != null)
        {
            onExit();
        }
    }
    #endregion

    public void OnDrag(PointerEventData eventData)
    {
        if (OnLeftBeginDrag != null)
        {
            OnLeftBeginDrag();
        }
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
        if (OnLeftDrag != null)
        {
            OnLeftDrag();
        }
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        if (OnLeftEndDrag != null)
        {
            OnLeftEndDrag();
        }
    }

}
1 Like

My Friend Told me to use OnMouseEneter/Exit or OnMouseOver. If my answer are not fit for you, you can choose Those default functions as well.

2 Likes

I know this topic is old but if anyone is having this problem this can be of great help, here is my code

private const string normalTrigger = "Normal";
private const string highlightedTrigger = "Highlighted";
private const string selectedTrigger = "Selected";

private bool isHighlighted = false;

private void Update()
{
    if (!isHighlighted)
    {
        if (tabController.CurrentTab != this)
        {
            var stateInfo = animator.GetCurrentAnimatorStateInfo(0);

            if (stateInfo.IsName(highlightedTrigger) && !stateInfo.IsName(selectedTrigger) && !animator.IsInTransition(0))
                animator.SetTrigger(normalTrigger);
        }
    }
}

public void OnPointerEnter(PointerEventData eventData)
{
    isHighlighted = true;

    if (tabController.CurrentTab != this)
    {
        var stateInfo = animator.GetCurrentAnimatorStateInfo(0);

        if (stateInfo.IsName(normalTrigger) || !stateInfo.IsName(selectedTrigger))
            animator.SetTrigger(highlightedTrigger);
    }
}

public void OnPointerExit(PointerEventData eventData)
{
    isHighlighted = false;          
}

I’m working on a VR menu and need to rely on OnPointer…

I have a popup that is triggered on pointer enter of a panel. When the point enters the popup it has buttons inside of it that can trigger point exit and I’m trying to figure out how to ignore internal elements , but when leaving the popup completely it doesn’t seem like OnPointerExit is trustworthy.

@GuidewireGames you might have figured it out already, but if you uncheck the “Raycast Target” on the GO/elements that you don’t want interacting with your pointer they’d stop doing so

If someone desperately needs to check if mouse is over a button reliably, you can always just use raycasting,

private void Update()
{
    RaycastHit2D hit = Physics2D.Raycast(Input.mousePosition, Vector2.zero);

    if (hit.collider != null)
    {
        Debug.Log("Mouse is over the button!");
    }
    else
    {
        Debug.Log("Mouse is not over the button!");
    }
}

Unfortunately, it’s not just OnPointerExit that sometimes doesn’t fire. OnPointerEnter also doesn’t work if you move your mouse too quickly, but at least that one makes sense.

Well! This does the trick for me! Thank you very much!