Enter and Exit pointer Called everySecond at UI Element

I I’m making a Info Panel element which show when the player mouse stay on a element in the game.

To do That I made a “popUpManager” which manage that.

I made a interface :

namespace Assets.script.GameManagers
{
    public interface IinfoOnMouseOver
    {
        void SetCallBackMethodeOnPLayerMouseOver(Action<string,string,string,string,string> callbackMethode);
        void SetCallBackMethodeDisplayInfo(Action<bool> callBackMethode);
       
        void SetTempoBeforCall(int deltaTime);
    }
}

Wich is implemented by all element which have info to display when the player mouse stay over.

the popUp manager get a reference of all the script implementing this interface and give then the calledback methode to says “Hey i’m focusing by the mouse you can set active the popup” and “Hey there is my info to display”.

public class PopUpInfoScriptManager : MonoBehaviour
{
    [SerializeField] GameObject InfoWindows;

    [SerializeField] TMP_Text Title;
    [SerializeField] TMP_Text Info1;
    [SerializeField] TMP_Text Info2;
    [SerializeField] TMP_Text Info3;
    [SerializeField] TMP_Text Info4;

    [SerializeField] int TempoBeforeDisplay = 1;
    private bool infoWindowsState;
    private List<IinfoOnMouseOver> InfoScriptList;

    Action<string, string, string, string, string> CallBackMEthodeGetInfo;
    Action<bool> CallBackMethodeDisplayWindows;
    // Start is called before the first frame update
    void Start()
    {
        InfoScriptList = FindAllInfoScript();
        CallBackMethodeDisplayWindows = TurnDisplayWindows;
        CallBackMEthodeGetInfo = GetInfoToDescription;

        foreach (IinfoOnMouseOver infoItem in InfoScriptList)
        {
            infoItem.SetCallBackMethodeDisplayInfo(CallBackMethodeDisplayWindows);
            infoItem.SetCallBackMethodeOnPLayerMouseOver(CallBackMEthodeGetInfo);
            infoItem.SetTempoBeforCall(TempoBeforeDisplay);
        }
    }
    // Update is called once per frame
   

    private List<IinfoOnMouseOver> FindAllInfoScript()
    {
        IEnumerable<IinfoOnMouseOver> InfoGameObjects = FindObjectsOfType<MonoBehaviour>(true).OfType<IinfoOnMouseOver>();

        return new List<IinfoOnMouseOver>(InfoGameObjects);
    }

    public void TurnDisplayWindows(bool switchTop)
    {
        infoWindowsState = switchTop;
        InfoWindows.SetActive(infoWindowsState);

        if (InfoWindows.activeSelf)
        {
            InfoWindows.transform.position = Input.mousePosition;
        }
    }

    public void GetInfoToDescription(string title, string info1, string info2, string info3, string info4)
    {
        Title.text = title;
        Info1.text = info1;
        Info2.text = info2;
        Info3.text = info3;
        Info4.text = info4;
    }
}

Then the manager show the the popup over the mouse position.

To the object calling back the manager to active the popUp I used the on Enter and Onexit whith Event trigger.

public class OverCardsInfoScript : MonoBehaviour, IinfoOnMouseOver
{
    [SerializeField] string Title;

    [SerializeField] string Info1;
    [SerializeField] string Info2;
    [SerializeField] string Info3;
    [SerializeField] string Info4;

    Action<string, string, string, string, string> callbackMethodeInfo;
    Action<bool> callBackMethodeTrigger;

    private int WaitTime = 1;

    bool isMouseOver = false;
    bool DataWasSended = false;

    public void SetCallBackMethodeDisplayInfo(Action<bool> callBackMethode)
    {
        callBackMethodeTrigger = callBackMethode;
    }

    public void SetCallBackMethodeOnPLayerMouseOver(Action<string, string, string, string, string> callbackMethode)
    {
        callbackMethodeInfo = callbackMethode;
    }

    public void SetTempoBeforCall(int deltaTime)
    {
        WaitTime = deltaTime;
    }


    public void OnMouseEnter()
    {
        isMouseOver = true;
        Debug.Log("Mouse Enter");
        StartCoroutine(waiter());
    }

    public void OnMouseExit()
    {
        Debug.Log("Mouse Exit");
        isMouseOver = false;
        if (DataWasSended)
        {
            callBackMethodeTrigger(false);
            DataWasSended = false;
        }
    }

    IEnumerator waiter()
    {  
        yield return new WaitForSecondsRealtime(WaitTime);

        if (isMouseOver)
        {
            callBackMethodeTrigger(true);
            callbackMethodeInfo(Title, Info1, Info2, Info3, Info4);
            DataWasSended = true;
        }

    }
}

The onMouseEnter and OnMouseExit methodes are called by the triggerEven Componant
8454875--1121978--upload_2022-9-21_11-37-59.png

It’s seems to work but the enter/exit are called both ones per second
8454875--1121987--upload_2022-9-21_11-39-1.png

So the popup instantly disappear.

My gameObject to catch the mouse over is a canvas attached to a gameObject in the scene :
8454875--1121990--upload_2022-9-21_11-40-32.png

8454875--1121993--upload_2022-9-21_11-41-6.png

Any Idea of what’s append?

Thanks for your Help.

No idea what happened but coroutines are not appropriate here.

Instead use a float as a timer:

private float hoverTime;

When the mouse is over the object, count up the timer. Else zero it:

if (MouseIsHoveringOverObject)
{
  hoverTime += Time.deltaTime;
}
else
{
  hoverTime = 0;
}

Finally, wherever you care about this:

if (!toolTipOpen)
{
  if (hoverTime >= 1.0f)
  {
    toolTipOpen = true;
    // do anything else for tooltip
  }
}

Coroutines are NOT always an appropriate solution: know when to use them!