Hey all,
So, using the top down template with some modified code (removed the touch settings and the vr headset stuff), for whatever reason, when I click the left mouse button it doesn’t use the callback function and it breaks the camera orbit function (the camera will pitch up and down, but not rotate left and right).
Here’s my code (sorry, it’s a lot):
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
#include "TopDown.h"
#include "TopDownPlayerController.h"
#include "Runtime/Engine/Classes/Components/DecalComponent.h"
#include "Runtime/Engine/Classes/Engine/LocalPlayer.h"
#include "TopDownCharacter.h"
// DEBUG
#include "Engine.h"
ATopDownPlayerController::ATopDownPlayerController()
{
DefaultMouseCursor = EMouseCursor::Crosshairs;
bShowMouseCursor = true;
}
void ATopDownPlayerController::PlayerTick(float DeltaTime)
{
Super::PlayerTick(DeltaTime);
}
// Input
//
void ATopDownPlayerController::SetupInputComponent()
{
// set up gameplay key bindings
Super::SetupInputComponent();
InputComponent->BindAxis("MoveForward", this, &ATopDownPlayerController::MoveForward);
InputComponent->BindAxis("MoveRight", this, &ATopDownPlayerController::MoveRight);
InputComponent->BindAxis("MouseHorizontal", this, &ATopDownPlayerController::MouseHorizontal);
InputComponent->BindAxis("MouseVertical", this, &ATopDownPlayerController::MouseVertical);
InputComponent->BindAction("ZoomIn", EInputEvent::IE_Pressed, this, &ATopDownPlayerController::ZoomIn);
InputComponent->BindAction("ZoomOut", EInputEvent::IE_Pressed, this, &ATopDownPlayerController::ZoomOut);
InputComponent->BindAction("LookAround", EInputEvent::IE_Pressed, this, &ATopDownPlayerController::LookAroundStart);
InputComponent->BindAction("LookAround", EInputEvent::IE_Released, this, &ATopDownPlayerController::LookAroundStop);
InputComponent->BindAction("LeftMouse", EInputEvent::IE_Pressed, this, &ATopDownPlayerController::OnClick);
}
void ATopDownPlayerController::ProcessPlayerInput(const float DeltaTime, const bool bGamePaused)
{
Super::ProcessPlayerInput(DeltaTime, bGamePaused);
const ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player);
ATopDownCharacter* Pawn = Cast<ATopDownCharacter>(GetPawn());
if(!LocalPlayer || !Pawn)
return;
// Scrolling
if(LocalPlayer->ViewportClient && LocalPlayer->ViewportClient->Viewport)
{
FVector2D MousePos;
if(!LocalPlayer->ViewportClient->GetMousePosition(MousePos))
return; // No mouse input to check
FViewport* Viewport = LocalPlayer->ViewportClient->Viewport;
const FIntPoint ViewSize = Viewport->GetSizeXY();
// TODO: Confirm this?
// Theory: LocalPlayer repesents the screen (Origin being dead center)
const uint32 ViewLeft = FMath::Trunc(LocalPlayer->Origin.X * ViewSize.X);
const uint32 ViewRight = FMath::Trunc(LocalPlayer->Size.X * ViewSize.X);
const uint32 ViewTop = FMath::Trunc(LocalPlayer->Origin.Y * ViewSize.Y);
const uint32 ViewBot = FMath::Trunc(LocalPlayer->Size.Y * ViewSize.Y);
// TODO: Add to Player Controller and expose to blueprints
const uint32 CameraActiveBorder = 32.0f;
// Check each border and the camera active area
const uint32 MouseX = MousePos.X;
const uint32 MouseY = MousePos.Y;
// TODO: do we need ViewLeft >= MouseX or just check if it's past the active border?
if(MouseX >= ViewLeft && MouseX <= (ViewLeft + CameraActiveBorder))
{
MoveRight(-1);
}
else if(MouseX >= (ViewRight - CameraActiveBorder) && MouseX <= ViewRight)
{
MoveRight(1);
}
if(MouseY >= ViewTop && MouseY <= (ViewTop + CameraActiveBorder))
{
MoveForward(1);
}
else if(MouseY >= (ViewBot - CameraActiveBorder) && MouseY <= ViewBot)
{
MoveForward(-1);
}
}
}
void ATopDownPlayerController::MoveForward(float Value)
{
APawn* const Pawn = GetPawn();
ATopDownCharacter* character = Cast<ATopDownCharacter>(Pawn);
if(character)
{
character->MoveForward(Value);
}
}
void ATopDownPlayerController::MoveRight(float Value)
{
APawn* const Pawn = GetPawn();
ATopDownCharacter* character = Cast<ATopDownCharacter>(Pawn);
if(character)
{
character->MoveRight(Value);
}
}
void ATopDownPlayerController::MouseHorizontal(float Value)
{
if(bLookAroundEnabled)
{
APawn* const Pawn = GetPawn();
Pawn->AddControllerYawInput(Value);
Cast<ULocalPlayer>(Player)->ViewportClient->Viewport->SetMouse(MouseLockPositionX, MouseLockPositionY);
}
}
void ATopDownPlayerController::MouseVertical(float axisValue)
{
if(bLookAroundEnabled)
{
APawn* const Pawn = GetPawn();
ATopDownCharacter* character = Cast<ATopDownCharacter>(Pawn);
if (character)
{
character->RotateCameraArm(FRotator(axisValue, 0.0f, 0.0f));
}
Cast<ULocalPlayer>(Player)->ViewportClient->Viewport->SetMouse(MouseLockPositionX, MouseLockPositionY);
}
}
void ATopDownPlayerController::ZoomIn()
{
APawn* const Pawn = GetPawn();
ATopDownCharacter* character = Cast<ATopDownCharacter>(Pawn);
if(character)
{
character->ChangeCameraArmLength(-1.0f);
}
}
void ATopDownPlayerController::ZoomOut()
{
APawn* const Pawn = GetPawn();
ATopDownCharacter* character = Cast<ATopDownCharacter>(Pawn);
if(character)
{
character->ChangeCameraArmLength(1.0f);
}
}
void ATopDownPlayerController::LookAroundStart()
{
//Lock mouse cursor
bLookAroundEnabled = true;
bShowMouseCursor = false;
MouseLockPositionX = Cast<ULocalPlayer>(Player)->ViewportClient->Viewport->GetMouseX();
MouseLockPositionY = Cast<ULocalPlayer>(Player)->ViewportClient->Viewport->GetMouseY();
}
void ATopDownPlayerController::LookAroundStop()
{
//Unlock mouse cursor
bLookAroundEnabled = false;
bShowMouseCursor = true;
}
void ATopDownPlayerController::OnClick()
{
// Display Camera Pitch
if(GEngine)
{
GEngine->AddOnScreenDebugMessage(0, 5.f, FColor::Red, "Click!");
}
}
//
// End Input
What’s really strange is that without the OnClick callback, this doesn’t happen. But if I left or right click, everything breaks.
After a few hours of looking this up online, I didn’t come up with anything to help solve this issue. Any suggestion would be greatly appreciated.