I have various actors in my game world that can respond based on the mouse’s position on the screen every tick. The problem is that when the mouse moves over the UI, the game world behind it is still responding to the mouse’s position on the screen. This looks odd as you can see things happening behind the semi-transparent UI while moving the mouse around. So, I’m wondering if there is some way to check if the mouse is currently over any UMG widget? Ideally, in the Tick function of an Actor, I’d like to be able to check, Is Mouse Over UI? If no, respond to mouse position on screen, if yes, ignore and drop out. I don’t mind writing C++ if I need to in order to expose something to Blueprint that will help me achieve this. Anyone have any ideas?
There is Is Hovered. You can add the elements you want to check to a widget array and check them in a for loop if you’ve got multiple ones.
In my BP I’m just checking whether EnteredWidget is true or not, if it’s false it checks for Is Hovered in another branch, if it’s true it sets EnteredWidget to true. In the next tick the execution flow will go to the true part of the branch and the single widget that was hovered is checked for if it’s hovered or not. In my case I’m not doing anything special if it’s still hovered, I’m just doing an animation with a timer to fade in and fade out the widget. But you could add a DoOnce node to the true branch and set the mouse mode to UI only for example.
Yeah I saw the Is Hovered, but was hoping there was a better way. It would mean I would need to iterate over every widget in the viewport and check if it Is Hovered, every single tick, which just seems wasteful.
In the widget override onMouseEnter and set game mode to UI only, in the same widget onMouseLeave sets the game mode back to Game&UI. If that’s not enough, dispatch a bool on widget Enter/Leave to prevent/allow game world interaction.
It seems wasteful but in reality my method used 0.025ms average on the game thread which didn’t seem like a lot. And when you’re packaging the project with nativized BPs it turns into an even smaller issue. If you wrap widgets within bigger widgets it’s not a huge performance hit. It might not be useful if you’re using modularized widgets however.
Thanks for all your suggestions. I’ve worked out a very fast C++ solution, so I can use it on Tick. Consider this case closed.
Would you mind sharing your solution?
Sorry this is pretty old now. I don’t remember or know where that code is anymore.
Use the “On Hovered” event
This was my solution.
Basically, you need to implement two functions on your widget.
virtual void NativeOnMouseEnter(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent) override;
virtual void NativeOnMouseLeave(const FPointerEvent& InMouseEvent) override;
Otherwise, you can try with “On Hovered” and “IsHovered()”.
Also, depends on how your widget is built and what you want to do. Just don’t forget that there are multiple events that can help you.
Set “Input Mode UI only” and set mouse to Do not Lock, then after ui work done “Input Mode Game Only” or “Input Mode Game and UI” and set mouse to Lock