Like the title says how do I detect those event in a C# script. I know that you can attach lets say a click event to a button via button.clickable.clicked += OnButtonClickEvent;.
But how do I do something similar for the mouseEnter, mouseLeave, mouseHover events on a panel or button?
Hey @Aniketos00,
To detect events such as mouseEnter and mouseLeave with UIElements you can use VisualElement.RegisterCallback<T>(EventCallback<T> callback)
.
An example usage might look like this: button.RegisterCallback<MouseEnterEvent>(HandleMouseEnter);
– assuming you had some function void HandleMouseEnter(MouseEnterEvent evt)
defined.
For a quick reference of all the supported events in UIElements, see the official Event Type Reference doc here.
Here’s a more thorough example, with a preview:

Assets/Editor/EventTester.uxml
<?xml version="1.0" encoding="utf-8"?>
<engine:UXML
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:engine="UnityEngine.UIElements"
xmlns:editor="UnityEditor.UIElements"
xsi:noNamespaceSchemaLocation="../../UIElementsSchema/UIElements.xsd"
>
<engine:VisualElement>
<engine:Style src ="EventTester.uss" />
<engine:Label name="testLbl" text="Try hovering and clicking this." />
</engine:VisualElement>
</engine:UXML>
Assets/Editor/EventTester.uss
Label {
border-width: 2px;
border-color: black;
font-size: 20px;
margin: 20px;
padding: 20px 0;
-unity-text-align: middle-center;
-unity-font-style: bold;
}
Assets/Editor/EventTester.cs
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
public class EventTester : EditorWindow
{
[MenuItem("Custom Tools/EventTester %#t")]
public static void ShowExample() { GetWindow<EventTester>(); }
public void OnEnable()
{
// Set up UI
var uiTemplate = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/EventTester.uxml");
var ui = uiTemplate.Instantiate();
rootVisualElement.Add(ui);
// Attach event handlers
var testLbl = ui.Q<Label>("testLbl");
testLbl.RegisterCallback<MouseEnterEvent>(HandleMouseEnter);
testLbl.RegisterCallback<MouseLeaveEvent>(HandleMouseLeave);
testLbl.RegisterCallback<MouseUpEvent>(HandleMouseUp);
testLbl.RegisterCallback<MouseDownEvent>(HandleMouseDown);
testLbl.RegisterCallback<ClickEvent>(HandleClick);
}
// Event handlers
void HandleMouseLeave(MouseLeaveEvent evt) { Debug.Log("HandleMouseLeave"); }
void HandleMouseEnter(MouseEnterEvent evt) { Debug.Log("HandleMouseEnter"); }
void HandleMouseDown(MouseDownEvent evt) { Debug.Log("HandleMouseDown"); }
void HandleMouseUp(MouseUpEvent evt) { Debug.Log("HandleMouseUp"); }
void HandleClick(ClickEvent evt) { Debug.Log("HandleClick"); }
}
Hope that helps!
Hello @Aniketos00
Take a look at EventTrigger component and Pointer Handler interfaces
EDIT
Almost every UnityEngine.UI has a component with a ‘raycast target’ option. That means that you can attach an EventTrigger to it that will do some actions when mouseEnter/mouseExit etc.
Take a look at the image above.
If an UI object has ‘Raycast target’ param that means that it can be interacted.
As you can see I have a simple image with EventTrigger component attached to it. I added 2 events to this EventTrigger:
‘Pointer Enter’ - that will execute when my mouse is over this image.
‘Pointer Exit’ - that will execute when I’ll move my mouse from the image.
You can also an EventTrigger to an object or add a new event to already created EventTrigger within a script.
Take a look at this answer: How to set EventTrigger parameters by C#? - Questions & Answers - Unity Discussions
As for Pointer Handler interfaces…
It is similar to EventTriggers except you create a script and attach it to the object you want to manipulate (correct me if I am wrong because I’m also kinda a newbie to this UI things):
Here is an example of my ToolTip script that show a little tooltip window when I hover over an UI on the canvas:
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class ToolTipDescription : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
public Text text;
public Image body;
public string description;
public void OnPointerEnter(PointerEventData eventData)
{
ShowTooltip();
}
public void OnPointerExit(PointerEventData eventData)
{
HideTooltip();
}
private void ShowTooltip()
{
body.gameObject.SetActive(true);
text.color = new Color(text.color.r, text.color.g, text.color.b, 1);
}
private void HideTooltip()
{
body.gameObject.SetActive(false);
text.color = new Color(text.color.r, text.color.g, text.color.b, 0);
}
}
I ended up creating a class that extends VisualElement and building off of the EventHandlers. I figured I would leave in the other methods and debug statements so you could see how they work, but the only two that I needed were HandleMouseLeave and HandleMouseEnter.
I don’t like it, and it definitely is not perfect, I would like to see something built into the new EventSystem ideally. I don’t know if there is a better way of handling it, but this is what I have implemented for the time being:
public class VisualElementExtension : VisualElement
{
public VisualElementExtension() : base()
{
this.RegisterCallback<MouseEnterEvent>(HandleMouseEnter);
this.RegisterCallback<MouseLeaveEvent>(HandleMouseLeave);
this.RegisterCallback<MouseUpEvent>(HandleMouseUp);
this.RegisterCallback<MouseDownEvent>(HandleMouseDown);
this.RegisterCallback<ClickEvent>(HandleClick);
}
void HandleMouseLeave(MouseLeaveEvent evt)
{
if (evt.target.GetType() == typeof(Menus))
return;
GameManager.Instance.MouseIsOverUI = false;
Debug.Log("HandleMouseLeave");
}
void HandleMouseEnter(MouseEnterEvent evt)
{
if (evt.target.GetType() == typeof(Menus))
return;
GameManager.Instance.MouseIsOverUI = true;
Debug.Log("HandleMouseEnter");
}
void HandleMouseDown(MouseDownEvent evt)
{
Debug.Log("HandleMouseDown");
}
void HandleMouseUp(MouseUpEvent evt)
{
Debug.Log("HandleMouseUp");
}
void HandleClick(ClickEvent evt)
{
Debug.Log("HandleClick");
}
}
My reasoning for excluding the Menus class from the check is because I have one object that handles controlling different menus that are being displayed, so this element is essentially always present. I just had to make the other visual element classes inherit from this instead of the base VisualElement class and it seems to be working fairly well.
In my GameManager singleton, I just hold the boolean value, so I don’t have to do any crazy raycasts or anything when checking if the mouse is over the UI.
Hope this helps, it is very frustrating trying to find solutions to problems with this new UI system, there are not a lot of great resources, and most people are still using the old system so if they try to help then they assume you’re using the old system.