- Home /
How can you control which Canvas(es) receives input?
I have multiple UI Canvases drawn to the screen at the same time in world space. They all share the same event Camera. However, when one UI appears on top of another, it seems arbitrary which Canvas actually receives input events.
Each canvas has a sorting layer set, but that seems to get completely ignored; occluded canvases receive input "through" other canvases that draw on top of them. Changing the Z position(s) to move them in front/behind of each other relative to the camera also doesn't seem to have any effect. Rearranging the objects in the hierarchy also doesn't seem to make a difference.
I did manage to get it "working" by using a separate event Camera for each Canvas with a manually-entered Depth setting, and camera depth seems to take priority, but that's really fragile at best (since Depth would need to get updated by hand everywhere any time sorting layers are changed/rearranged) and it requires a lot of redundant cameras.
How can I make it so that the canvas drawn in front always receives input events? There doesn't seem to be any feasible way to control it.
This is a decent question. To my knowledge, the first detected (topmost) UI element will receive and consume mouse events regardless of what canvas it belongs to. Perhaps this was chosen as the default behavior because it's assumed desirable more often than not. $$anonymous$$nowing how to circumvent this seems like a reasonable request. Any takers?
the first detected (topmost) UI element will receive and consume mouse events regardless of what canvas it belongs to
What's the criteria for topmost in this case? It's possible I have something set up wrong, but I'm running into situations like a button is directly on top of another but the button behind it is what is receiving input.
Imagine two canvases and four overlapping (relative to the game camera) interactable elements in the scene hierarchy:
Canvas
--Element
--Element
Canvas
--Element
--Element <- should draw atop and consume events
Can you confirm that this resembles your situation but you're finding this isn't the case?
I've been running into situations where the (invisible) RectTransform of an element or group of elements is improperly sized - meaning it does not exactly match the shape of the elements it contains - and this has been giving me all kinds of focus issues. This can happen very easily if you don't pay close attention to every little change in size or position of nested elements. $$anonymous$$ight wanna ensure that's not happening.
Yep! They do draw correctly, but input goes "through" the topmost UI until I disable the one behind it.
It is worth noting that the Canvases are positioned in World Space, not Screen Space. That said, I've tried moving them around in world space to move them in front of/behind each other, verified that they have the same event camera and that it sees both canvases, moved them around in the hierarchy to see if that ordering mattered, etc. The rect transforms seem to fit the UI elements properly. Screen B only receives input when I disable Screen A even though Screen B is "in front" by every standard I can think of.
It's also plausible that I've run into a Unity engine bug, but I try to not blame the engine unless I've exhausted all other possible options. :)
Definitely a decent question then. I'm sorry I'm not able to be of more help. If you don't want to disable the offending items, consider setting their interactive state to false, or slap a script on them like so (write in a bool toggle if that's more convenient)...
using UnityEngine;
public class UIIgnore$$anonymous$$ouseEvents : $$anonymous$$onoBehaviour, ICanvasRaycastFilter
{ public bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera) { return false; } }
Your answer
Follow this Question
Related Questions
Use Unity UI For 2D Games Or Custom Objects Instead? 2 Answers
How to add sprites to a canvas via scripting 1 Answer
Canvas Scaler - scaleFactor 0 Answers
Move UI image on top of other elements 0 Answers