UE5 Widgets - How to "consume" mouse click?

I am building a tower defence game, where the player can freely use their mouse to click actors on screen (e.g. to click on a tower to see it’s stats, or click a rock to collect stone). Sometimes, I want widgets that the user can click, but then I want this mouse click to be “consumed” so they do not interact with the world behind the widget.

My setup so far is a “WBP_UI” widget which holds all of the UI widgets (e.g. showing resources, buttons to start wave, health, game speed, etc). The canvas panel of this base UI widget is Visible and hit-testable. It overrides the “Mouse Down” event and calls some C++ functions which handle my actual game logic, for example to collect a resource on the ground under the cursor. (simplified BP below)

I then have some “WBP_TowerCard” widgets which are widgets to act as the buttons for the user to select what type of tower to place down. These are created by the WBP_UI on event construct and placed in a HorizontalBox. These tower cards should have their own logic for handling a user clicking them, and so are also Visible/hit-testable and override the “Mouse Down” event. They also have some logic to animate when the mouse is over them and so implement animations on the “On Mouse Enter” and “On Mouse Leave” events. For example, these tower cards might become larger when hovered, and stay larger when clicked to indicate they are selected, and set the player mode to “placing” so the next click in the world attempts to place the selected tower down. In this instance, I do NOT want the click to propagate to the WBP_UI widget. (simplified BP below)


This is because I get issues such as selecting a tower and placing the tower on the ground behind the card in the same click, instead of 1 click to select the tower, and then a second click to place the tower. How can I get the click to be “consumed” by the WBP_TowerCard so the logic in the WBP_UI::OnMouseDown does not run?

I also have an issue where on clicking the TowerCard, it also calls the OnMouseLeave event when clicking down and OnMouseEnter event when releasing the click, which should not be happening as the cursor does not actually leave the edges of the card (which is what I want these events for, as they are meant to handle hover animations). In my blueprint, these events play animations to raise the card up and down to indicate they are the card being hovered over. However, when clicking the card they lower briefly before coming back up, which is not intended. I am not sure if this is something that is caused by the click propagation but it causes annoying unintended visual effects.

These are the output strings printed from the above blueprints when I start the game, move the mouse over my WBP_TowerCard, and then click once without moving my mouse.

The two logs with the green dots are expected, the logs with the red dots are not expected and cause unintended effects.

Thanks for any help!

NOTE:
I noticed that when using generic Button widgets instead of a custom WBP_TowerCard, the button is able to consume the click and perform it’s own logic without calling the WBP_UI OnMouseButtonDown function. What is the button actually doing to do this? I suppose one workaround would be to make my WBP_Towercard a child of a “Button Widget” instead of a “User Widget” and handle my logic in the Button::OnClicked event instead of overriding the UserWidget::OnMouseDown function, but I want to know how it actually works so I can implement it without changing my widget inheritance heirarchy.

Look into Set Input Mode UI Only :slight_smile: that’s where you’ll be able to set the controls in the widget only!

Hey, that seems to fix the secondary issue of calling the OnMouseLeave and OnMouseEnter events, but causes other input related issues. e.g. I use WASD to move the camera around. If the camera is moving while the card is clicked, setting the input mode to UI only makes the camera continue to move to the side even if the player stops holding a movement key. This is not intended and I want the user to be able to continue to control movement and handle inputs even when UI buttons are used.

Mmmmh How about Set Input Mode Game and UI? I haven’t done much about widgets but know that much. Otherwise you can probably hard code it to put the velocity/camera speed at 0 before it opens the widget. Sort of to force it to stop. That’s as much as I can do or think for now.

Thank you, that does seem to fix the issue with the OnMouseleave and OnMouseEnter events being called when clicked!

However, I am still having problems with the click not being consumed and so the OnMouseButtonDown functions for both my WBP_UI and WBP_Towercard are being called in the same click each time, instead of just for the WBP_TowerCard, so if anyone else could help that would be great :slight_smile:

If anybody else finds this post with the same issue, I was not able to “fix” it and I still don’t know how to stop the click propagating, but I have a workaround working.

Basically the root widget of my custom WBP_TowerCard is a button, set to Visible so it can be clicked. The opactiy of the button is set to 0, and all my logic that was previously in the “On Mouse Button Down” override function is now handled in the button’s built in “On Click” event.

I also had issues visually with the button having rounded corners and there being space on the sides even with 0 padding. This is because the button by default has rounded corners. If you go to the button “Style”, you can set the draw mode to be as “Image” or “Box” instead of “Rounded Box” and it gets rid of the rounded corners which apply some form of padding.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms