I'm trying to have UI Toolkit made layouts over my game scene in Unity. The UI covers entire screen (I want to display modal dialogs in center) and roughly bottom 20% of screen contains some buttons.
On the buttons, I have clicked actions that work fine, but once the button is clicked, the event 'falls through' to underlying GameObject, triggering another 'in-game' (unlike in-ui) action.
How do I prevent propagation of clicks into UIToolkit ui to underlying scene filled with GameObjects?
I tried almost everything I found and read in docs and forums but with no luck. I tried differentiating layers (I've put GameUI scene object containing the UIDocument into UI layer and World scene object containing my gameObjects into custom World layer), but the raycast hit still says that the target object is GameObject of 'in-scene' type, not VisualElement of Panel or something like this.
This is the solution:
https://forum.unity.com/threads/ui-toolkit-and-raycast-block.1034938/#post-8218593
The thing is: I wanted to build primarily for handheld/touchscreen devices, thus MouseEnterEvent and MouseLeaveEvent didn't actually made much sense to me, but, BUT... The MouseEnterEvent triggered on VisualElement is not triggered when pointer hovers over UI, but when poiinter clicks inside the ui -> Gives focus to it, the same with mouse leave, you need to click/tap outside the VisualElement and I believe there is confision about terminology, as this seems more like "ElementWasGivenFocusEvent" rather than MouseEnter/Leave.
The complete solution now looks something like this:
bool inBar = false;
void Start() {
topBarContainer = rootUiVisualElement.Q("TopBar");
bottomBarContainer = rootUiVisualElement.Q("BottomBar");
topBarContainer.RegisterCallback<MouseEnterEvent>((evt) =>
{
Debug.Log("Mouse Enter TOP");
if (evt.target == topBarContainer)
{
inBar = true;
}
});
topBarContainer.RegisterCallback<MouseLeaveEvent>((evt) =>
{
Debug.Log("Mouse Leave TOP");
if (evt.target == topBarContainer)
{
inBar = false;
}
}); }
//analogically for bottom bar
void Update() {
if (!inBar)
{
Ray ray = mainCamera.ScreenPointToRay(position);
if (Physics.Raycast(ray, out RaycastHit hit) && hit.collider)
{
//do something useful
}
} }