In a top-down building placement game I am using “Set Input Mode Game And UI” in order to allow both UI actions and the player controller to move the camera. Option “Hide Cursor During Capture” is set to True, in order to lock and hide the cursor while the camera is rotated and moved via RMB and MMB. The problem is that I cannot seem to find the option to exclude LMB from capture. As it is now, clicking and holding LMB makes the cursor disappear, which I do not want as I use it for placement.
I tried setting “Hide Cursor During Capture” to false, and hiding the cursor manually when camera operations happen. The problem is that in this mode the cursor is not centered. The hidden cursor runs out of screen space and camera cannot be moved further. Manually centering the cursor while hidden breaks input actions as they are considering no movement is made.
Thanks for the idea, just tried it. As you noted, this doesn’t capture the mouse on MMB, so the cursor is still shown. But, it introduces another problem: when mouse isn’t captured, the game does not receive events. So in this solution neither LMB nor MMB events are passed to the game.
So, I should reformulate the problem: I want the cursor to be captured, but hot hidden, just on LMB.
Well you could try putting the capture mode as “Capture Permanently Including Initial Mouse Down”.
Then in your Right Click and MM Click input events, call a function that handles the camera rotation input, but also enables and disables “Show Cursor”.
These also trigger a boolean on the player controller. This way in your widgets you can override “On Preview Key Down”, and it can check if that boolean is active on the controller. If the boolean is true, pass unhandled, if its false, pass handled.
This way you can’t still Left Click UI elements while you’re rotating the camera
I have this exact same problem and solution I found somewhat unsatisfying. I set input mode to game and ui whenever LMB pressed in tick. I hope this helps but I believe this going to cause other problems of its own in the future. Also reason is whenever LMB pressed input mode is set to game only by default in ue.
”Capture During Right Mouse Down” consumes all the other mouse buttons so I can’t have the player controller use LMB to do something… otherwise it’s what I need.
Weird thing is that “mouse up” is still called in the player controller… just not mouse down… is the behavior a bug or something??
I think the relevant c++ is in one of these (or multiple):
GameViewportClient.h
GameViewportClient.cpp
SViewport.h
SViewport.cpp
SlateApplication.h
SlateApplication.cpp
but I only know some very basic c++ and can’t figure out how I can override what happens with the input to let all the mouse inputs besides RMB make it to the player controller while RMB dragging like normal.
I’m not. Opening a blank third or first person project and putting this in a custom player controller is all you need to do to replicate the problem. (I’m using UE5.5)
I just came back to look at this and I see it hasn’t been solved. So in case you haven’t solved it on your end yet, I went ahead and tried an implementation in a new project.
I got something that seems to be working how you described. That being:
Only when holding Left Ctrl + RMB can the player be controlled
When either Ctrl OR RMB is let go, it returns the mouse cursor to the screen and disables controls for the player.
Understanding what each UI input routing function does helps to understand what we need to do.
Mouse capture mode simply determines the behavior of what happens when we either first click onto our program, or when we click back onto it after interacting with a different program. We can simply set it to “Capture Permanently Including Initial Mouse Down” in begin play, rather than setting it every time we change our input mode. This will mean we won’t have to click the screen twice to press a button after we were messing with a program on a different montior.
Setting the Input Mode tells Unreal how our inputs are going to be routed: Either through the game (like on the player), through the UI, or through both.
So I have an event that handles the flow of whether or not we should be in our UI interaction mode, or our player control interaction mode here. You can also manually update whether we show the cursor or not instead of just automatically hiding it.
Inside this macro, we add these input to an array of our listened inputs. Then we check the array to see if it has all of the required inputs. Based on this condition, we decide which input mode we want