What I want is this:
- The mouse cursor is locked to the game window.
- When right mouse button is held down:
- The mouse cursor is hidden
- Mouse movement affects camera angle.
- When right mouse button is not held down:
- The mouse cursor is shown.
- Mouse movement affects cursor position.
Very normal really.
What I have is this…
DefaultInput.ini:
bCaptureMouseOnLaunch=False
DefaultViewportMouseCaptureMode=CaptureDuringRightMouseDown
DefaultViewportMouseLockMode=LockAlways
What happens is that when the game starts, the mouse cursor is shown, but not locked to screen. If I move it off the game screen and back again, then it becomes hidden within the game window. If I press the right mouse button while the cursor is visible, it is hidden, but not shown again when I release the right mouse button.
I changed DefaultInput.ini to have:
DefaultViewportMouseLockMode=LockInFullscreen
No difference.
I changed DefaultInput.ini to have:
DefaultViewportMouseLockMode=LockOnCapture
No difference.
I am a bit frustrated because earlier with, as far as I can remember, identical settings the cursor was initially locked to the game screen, just not after I pressed the right mouse button.
I have tried the code below, but it made no difference.
CustomPawn.cpp:
void CustomPawn::BeginPlay()
{
APlayerController *controller;
Super::BeginPlay();
controller = Cast<APlayerController>(GetController());
if (nullptr != controller)
{
FInputModeGameAndUI input_mode;
input_mode.SetLockMouseToViewportBehavior(EMouseLockMode::LockAlways);
input_mode.SetHideCursorDuringCapture(true);
controller->SetInputMode(input_mode);
}
}
How do I get the mouse input to behave as I wish?
I have checked the code in Engine/Private/Slate/SceneViewport.cpp and can see what it is meant to be doing. The code all looks sensible at a brief glance. It just is not doing it.
This is fairly horrible code and probably a lot more than I need, but…
I registered call backs for RMB press and release and implemented them as follows…
Press:
UGameViewportClient *viewport_client = GetWorld()->GetGameViewport();
TSharedPtr<SViewport> viewport_widget = viewport_client->GetGameViewportWidget();
ULocalPlayer *player = _GetLocalPlayer();
if (!viewport_widget.IsValid())
{
UE_LOG(LogTemp, Warning, TEXT("Invalid widget!"));
}
else if (nullptr == player)
{
UE_LOG(LogTemp, Warning, TEXT("Invalid player!"));
}
else
{
TSharedRef<SViewport> widget_ref = viewport_widget.ToSharedRef();
FReply &slate = player->GetSlateOperations();
Cast<APlayerController>(GetController())->SetShowMouseCursor(false);
FSlateApplication::Get().SetAllUserFocusToGameViewport(EFocusCause::Cleared);
FSlateApplication::Get().OnCursorSet();
slate.UseHighPrecisionMouseMovement(widget_ref);
slate.LockMouseToWidget(widget_ref);
viewport_client->SetMouseLockMode(EMouseLockMode::LockAlways);
viewport_client->SetIgnoreInput(false);
viewport_client->SetMouseCaptureMode(EMouseCaptureMode::CapturePermanently);
}
Release:
UGameViewportClient *viewport_client = GetWorld()->GetGameViewport();
TSharedPtr<SViewport> viewport_widget = viewport_client->GetGameViewportWidget();
ULocalPlayer *player = _GetLocalPlayer();
if (!viewport_widget.IsValid())
{
UE_LOG(LogTemp, Warning, TEXT("Invalid widget!"));
}
else if (nullptr == player)
{
UE_LOG(LogTemp, Warning, TEXT("Invalid player!"));
}
else
{
TSharedRef<SViewport> widget_ref = viewport_widget.ToSharedRef();
FReply &slate = player->GetSlateOperations();
Cast<APlayerController>(GetController())->SetShowMouseCursor(true);
FSlateApplication::Get().SetAllUserFocusToGameViewport(EFocusCause::Cleared);
slate.LockMouseToWidget(widget_ref);
slate.ReleaseMouseCapture();
viewport_client->SetMouseLockMode(EMouseLockMode::LockOnCapture);
viewport_client->SetMouseCaptureMode(EMouseCaptureMode::CaptureDuringRightMouseDown);
}
Now I need to spend a few hours removing lines of code to see which ones are redundant.
The mouse is still not restricted to the viewport though.
1 Like