4.14.1
Functionality:
- Right Click drag looks around (.2 sec
to initiate hold) - Record the mouse position at the time of held click to place the cursor back at the same position once RMB up event fires.
- Right click still available
- Left click available
- WASD keys move character as normal
In PIE this works fine as expected.
In Standalone, the mouse cursor never stays in the game windows. It acts sporadic and unpredictably in the upper left hand of the monitor the game window is in. I have to close the window in the Windows task bar.
Windows 10 Pro Version 1607, OS Build 14393.447, 64 bit, 64g RAM, i7-5820 CPU @ 3.3GHz
3 Monitors on a GeForce GTX 970, 4g memory
- Launch 4.14.1 from the Epic Launcher
- Create new C++ Third Person Example, Desktop/Console, Max Quality, no starter content
- Create new BLUEPRINT in the ThirdPersonCPP/Blueprints folder, inherit from GameModeBase, called “MyGameModeBase”
- Create new C++ class, Inherit from PlayerController, called “MyPlayerController”.
- Go into ThirdPersonCPP/Blueprints folder, open up “MyGameModeBase” blueprint and change Player Controller Class to “MyPlayerController”.
- In the blueprint “MyGameModeBase”, change Default Pawn Class to “ThirdPersonCharacter”
- Go into Project Settings, change Default GameMode to “MyGameModeBase”
- Go into Project Settings, Input, add Action mapping “RightMouseButton”, assign to Right Mouse Button
- Go into Project Settings, Input, add Action mapping “LeftMouseButton”, assign to Left Mouse Button
- Delete the ThirdPersonCharacter placed on the mapping
- Drag in a PlayerStart from the Modes tab
- Go into the Projects “.h” file, change “#include EngineMinimal.h” to “Engine.h”
MyPlayerController.h
*/
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "GameFramework/PlayerController.h"
#include "GameFramework/Character.h"
#include "MyPlayerController.generated.h"
USTRUCT()
struct FMouseCursor
{
GENERATED_BODY()
UPROPERTY()
float X;
UPROPERTY()
float Y;
};
/**
*
*/
UCLASS()
class TESTINGMOUSE_API AMyPlayerController : public APlayerController
{
GENERATED_BODY()
AMyPlayerController(const FObjectInitializer& ObjectInitializer);
virtual void BeginPlay() override;
public:
virtual void SetupInputComponent();
/* Handle to manage the timer for Right Mouse Button held*/
FTimerHandle RMBTimerHandle;
protected:
void AddYawInputCustom(float Val);
void AddPitchInputCustom(float val);
void OnRightMouseDown();
void OnRightMouseUp();
void OnLeftMouseDown();
void OnLeftMouseUp();
private:
void OnRightMouseButtonHeldDown();
float RightMouseButtonHoldInterval;
bool bIsRightMouseButtonHeld;
bool bIsLeftMouseButton;
FMouseCursor LastMouseCursor;
};
MyPlayerController.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "TestingMouse.h"
#include "MyPlayerController.h"
AMyPlayerController::AMyPlayerController(const class FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
bShowMouseCursor = true;
bIsRightMouseButtonHeld = false;
bIsLeftMouseButton = false;
RightMouseButtonHoldInterval = 0.2f;
}
void AMyPlayerController::BeginPlay()
{
Super::BeginPlay();
/* This is to allow input even when the cursor is at the edge of the screen*/
//FInputModeGameOnly GameMode;
FInputModeGameAndUI GameModeUI;
this->SetInputMode(GameModeUI);
}
void AMyPlayerController::SetupInputComponent()
{
Super::SetupInputComponent();
InputComponent->BindAxis("Turn", this, &AMyPlayerController::AddYawInputCustom);
InputComponent->BindAxis("LookUp", this, &AMyPlayerController::AddPitchInputCustom);
InputComponent->BindAction("RightMouseButton", IE_Pressed, this, &AMyPlayerController::OnRightMouseDown);
InputComponent->BindAction("RightMouseButton", IE_Released, this, &AMyPlayerController::OnRightMouseUp);
InputComponent->BindAction("LeftMouseButton", IE_Pressed, this, &AMyPlayerController::OnLeftMouseDown);
InputComponent->BindAction("LeftMouseButton", IE_Released, this, &AMyPlayerController::OnLeftMouseUp);
}
void AMyPlayerController::OnRightMouseDown()
{
UE_LOG(LogTemp, Warning, TEXT("right button DOWN"));
GetMousePosition(LastMouseCursor.X, LastMouseCursor.Y);
//GetWorld()->GetTimerManager().SetTimer(RMBTimerHandle, this, &AAWPlayerController::OnRightMouseButtonHeldDown, RightMouseButtonHoldInterval, false);
GetWorldTimerManager().SetTimer(RMBTimerHandle, this, &AMyPlayerController::OnRightMouseButtonHeldDown, RightMouseButtonHoldInterval, false);
UE_LOG(LogTemp, Warning, TEXT("right button DOWN EXIT"));
//bIsRightMouseButtonHeld = true;
}
void AMyPlayerController::OnRightMouseButtonHeldDown()
{
if (!bIsRightMouseButtonHeld)
{
GetMousePosition(LastMouseCursor.X, LastMouseCursor.Y);
}
bIsRightMouseButtonHeld = true;
UE_LOG(LogTemp, Warning, TEXT("HELD right button DOWN"));
}
void AMyPlayerController::OnRightMouseUp()
{
// Ensure the RMB timer is cleared
GetWorldTimerManager().ClearTimer(RMBTimerHandle);
if (bIsRightMouseButtonHeld)
{
FViewport* myviewport = CastChecked<ULocalPlayer>(this->Player)->ViewportClient->Viewport;
myviewport->SetMouse(LastMouseCursor.X, LastMouseCursor.Y);
}
else
{
}
bIsRightMouseButtonHeld = false;
UE_LOG(LogTemp, Warning, TEXT("right button UP"));
bShowMouseCursor = true;
}
void AMyPlayerController::OnLeftMouseDown()
{
UE_LOG(LogTemp, Warning, TEXT("LEFT button down"));
bIsLeftMouseButton = true;
}
void AMyPlayerController::OnLeftMouseUp()
{
UE_LOG(LogTemp, Warning, TEXT("LEFT button up"));
bIsLeftMouseButton = false;
}
void AMyPlayerController::AddYawInputCustom(float Val)
{
if (bIsRightMouseButtonHeld)
{
//Release the mouse events and don't draw the mouse
bShowMouseCursor = false;
if (Val != 0.f && this->IsLocalPlayerController())
{
AddYawInput(Val);
}
}
}
void AMyPlayerController::AddPitchInputCustom(float Val)
{
if (bIsRightMouseButtonHeld)
{
bShowMouseCursor = false;
if (Val != 0.f && this->IsLocalPlayerController())
{
AddPitchInput(Val);
}
}
}