Prevent clicking on GameObject through UI

Hello everyone!

In my Unity 2021.1.6f1 main scene I’ve got multiple GameObjects that have a script on them (different scripts for different objects) that detects a click with “OnMouseDown()” and opens a half-transparent menu. The canvas that contains all menu panels is at the very bottom of the hierarchy, the “Raycast Target” box is ticked (by default) on all panels and they’re all set to the UI layer. The problem is, I can click GOs through the menu panels and it triggers the GO’s “OnMouseDown()”!

I googled before writing this and there are a lot of posts that say that a canvas sized panel with a ticked “Raycast Target” box should prevent this from happening but I can still click through that panel and also through the old menu panels.

Another suggestion was to check for clicks in “Update()” of a GO but that seems like it could cause performance issues if there are multiply GOs that are clickable.

A third suggestion:

if(EventSystem.current.IsPointerOverGameObject()) {
    Debug.Log("Clicked on the UI");
}

I added this to “Update” of one of the script that handles the “opening” of a menu (it simply hides/unhides the parent panel) but not only did opening the panel now seem quite buggy but clicks through the UI are still possible.

Last suggestion: Add a static boolean (inside a static class) that is set when a menu is opened/closed and is checked whenever a GO is clicked. This only works of course if you actively use it (and don’t forget it) but seems more like a band-aid than an actual fix.

How do I prevent clicks through my menus? Is there anything that I don’t have to add to every “Update” function of every clickable object? Did I use “IsPointerOverGameObject” incorrectly?

2 Likes

Hi

Have you looked at the UI canvas layer sort order and also tried adding this to the panel;

7229191--869869--upload_2021-6-11_13-58-44.png

for instance I just made a canvas and made it block my game/and other canvas’s with a higher sort order

2 Likes

I would use Unity.EventSystems interface to solve this problem. See part 3 of this video

5 Likes

@Ian_1337
My canvas’ raycaster’s blocking mask was set to “Mixed” but everything, apart from “Everything”, was already ticked. I ticked “Everything” too, then set the sort order to 55 but I can still click through the panels once they’re un-hidden.

@Munchy2007
I found that video too before I started this thread. The guy said that he wouldn’t use the “EventSystem” way (1) in new projects, plus I’ve got multiple objects that are clickable, some are even only generated at runtime. Way 2 (“Event Trigger”) requires an event trigger on every clickable object. He recommends way 3 (with the “IPointerClickHandler”) but again, you need that code on every clickable object.
The video was uploaded in 2014, have there really been no changes to the canvas since then, something that allows you to generally blocks clicking through and that you put on the canvas instead of marking every clickable GO for it?
Edit: I just tested way 3 (“IPointerClickHandler” + Physics Raycaster) with 2 different clickable objects: 1. a TextMesh Pro text, 2. a regular GameObject (.obj file that I imported). Both objects use a regular box collider with “Is Trigger” ticked but the “OnPointerClick” function doesn’t trigger with either, only “OnMouseDown” seems to work. Not sure if the raycaster needs specific settings or what the problem is exactly.

I wanted to chime in here that the EventSystem.current.IsPointerOverGameObject() works well for me; however, there was an issue I had in which all of my clicks were hitting my UI elements when they were not. The culprit ended up being the Physics Raycaster that was on the Main Camera in the scene. Apparently, it and the Graphics Raycaster must have been clashing, and despite removing the Physics Raycaster, everything worked just fine.

1 Like

Thank you ! My Camera had also a Physics Raycaster conflicting with the one on my Canvas.

Hello @SimRuJ found your other question too, responding on both. Had the same problem in Unity 2021.3.3
Had an important component deactivated and just remembered “Raycast Target” doesn’t work on it’s own.

Solved it on this thread:

It’s the right way of doing it, no external components, just the default UI configs

Tidbit if you’re using 2 cameras make sure the Game Camera is a lower priority than the UI Camera. If it is the UI should block the events to game objects.

1 Like

I faced the same issue a while ago. As the other answers suggest, using Graphic Raycaster component and checking whether a UI element has been hit by the raycast is the way to go.

I wrote a small blog post that explains how to implement it in any project: Preventing clicks from going through UI elements in Unity.

1 Like