How to disable mouse cursor movement temporarily?

I have a top down game where I’d like to be able to lock the mouse in place whilst rotating the camera around the player (currently done via holding right click + looking around with mouse).

I am currently doing this by saving the mouse position before the right click and constantly resetting the mouse position to it in the OnLook event callback, but it is not ideal as it’s messy and buggy.

Is there a way to programmatically disable cursor movement, while still getting the mouse move input? Preferably in C++ but blueprints is ok too. Any help much appreciated! :slightly_smiling_face:

You want to take a look at software cursors, with those you can. If you try to set the position of a hardware cursor it will be out of sync with the OS cursor resulting in glitches. Scan the engine source for class FAnalogCursor

2 Likes

You might consider some type of “player state” system. All our projects have a PlayerState and PlayerSubState types that 100% determine how / what the player can interact with and what is displayed on the UI.

That said, here is a code snippet to change the mouse input settings in C++. This is in our BasePlayerController (inherits from the standard Unreal PlayerController class).

It switches on a “player state” and applies an “FInputMode” which afaik is the standard C++ way to change the mouse input settings.

There are multiple ways to approach taking the cursor away from the player. What we do is just hide it. Then when the player gets mouse cursor back it is centered on the screen.

void ABasePlayerController::UpdateMouseCursor()
{
	PlayerStateType stateType = GetCurrentPlayerStateType();
	LOG("ABasePlayerController::UpdateMouseCursor() %s", *(UEnum::GetValueAsString(stateType)));

	// never allow click or mouse events for unreal actors or components
	bEnableClickEvents = false;
	bEnableMouseOverEvents = false;

	// current player state type determines mouse behavior
	if (GetWorld())
	{
		switch (GetCurrentPlayerStateType())
		{
			// paused, interacting, fixed - game and UI
			case PlayerStateType::PAUSED:				
			case PlayerStateType::INTERACTING:
			case PlayerStateType::FIXED:
			case PlayerStateType::HMI:
			case PlayerStateType::STUNNED:
			case PlayerStateType::DEAD:
			{
				FInputModeGameAndUI mode;
				mode.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);
				SetInputMode(mode);
				bShowMouseCursor = false;
				DefaultMouseCursor = EMouseCursor::None;
				CenterMouseOnScreen();
				FocusGameWindow();
				break;
			}

			// walking, stationary, transition - game only
			case PlayerStateType::WALKING:
			case PlayerStateType::STATIONARY:
			case PlayerStateType::CHARACTER_TRANSITION:
			{
				FInputModeGameOnly mode;
				SetInputMode(mode);
				bShowMouseCursor = false;
				DefaultMouseCursor = EMouseCursor::None;
				FocusGameWindow();
				break;
			}

			// main menu - UI only
			case PlayerStateType::MAIN_MENU:
			{
				FInputModeGameAndUI mode;
				mode.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);
				SetInputMode(mode);
				bShowMouseCursor = true;
				DefaultMouseCursor = EMouseCursor::Hand;
				CenterMouseOnScreen();
				FocusGameWindow();
				break;
			}

			default:
			{
				LOG("ABasePlayerController::UpdateMouseCursor() invalid state type: %s", *(UEnum::GetValueAsString(stateType)));
				break;
			}
		}
	}
}

Documentation:

FInputModeGameAndUI | Unreal Engine Documentation

FInputModeGameOnly | Unreal Engine Documentation