Mouse Left-Click not registering and breaks other functionality

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.

Hey Mastersmith98 ,

Do you have “LeftMouse” set in your Input settings? These are in Project Settings → Input → Action Bindings.

Yep! And I have the game capturing mouse input and locking it as well in the editor preferences.

I just noticed that your SetupInputComponent function is different than what I’ve always seen.

This is how it’s normally setup (notice the difference in function argument):

void ATCharacter::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
	Super::SetupPlayerInputComponent(InputComponent);

    InputComponent->BindAction( "LeftMouse", IE_Pressed, this, &ACharacter::OnClick);
}

Hey,

That’s because it’s in the controller. It’s version of the function is different.

Source: Listening to Input in PlayerController - C++ - Epic Developer Community Forums

Ahh, I didnt realize. I will check this out asap.

Hey, thanks. I appreciate the assistance.

Hey Mastersmith98,

To start, I am not seeing any issues on my end regarding Left Mouse Button and any interference. Here is my setup:

[gamemode.h]

#pragma once

#include "GameFramework/GameMode.h"
#include "AH501536GameMode.generated.h"

UCLASS()
class AH501536_API AAH501536GameMode : public AGameMode
{
	GENERATED_BODY()
	
public:
    AAH501536GameMode( );	
};

[gamemode.cpp]

#include "AH501536.h"
#include "AH501536GameMode.h"
#include "TCharacter.h"
#include "TController.h"

AAH501536GameMode::AAH501536GameMode( )
{
    static ConstructorHelpers::FClassFinder<APawn> PawnAsset( TEXT("/Game/Character_BP") );    
    if( PawnAsset.Succeeded( ) )
    {
        DefaultPawnClass = PawnAsset.Class;
    }
    
    PlayerControllerClass = ATController::StaticClass( );
}

[character.h]

#pragma once

#include "GameFramework/Character.h"
#include "TCharacter.generated.h"

UCLASS()
class AH501536_API ATCharacter : public ACharacter
{
	GENERATED_BODY()

public:
	ATCharacter();
	virtual void BeginPlay() override;
	virtual void Tick( float DeltaSeconds ) override;
};

[character.cpp]

#include "AH501536.h"
#include "TCharacter.h"

ATCharacter::ATCharacter()
{
    PrimaryActorTick.bCanEverTick = true;
}

void ATCharacter::BeginPlay()
{
	Super::BeginPlay();
}

void ATCharacter::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );
}

[controller.h]

#pragma once

#include "GameFramework/PlayerController.h"
#include "TController.generated.h"

UCLASS()
class AH501536_API ATController : public APlayerController
{
	GENERATED_BODY()
	
public:
    virtual void SetupInputComponent( ) override;
	
    void OnClick( );
    void Forward( float A );
    void Right( float A );
    void YawInput( float A );
    void PitchInput( float A );
};

[controller.cpp]

#include "AH501536.h"
#include "TController.h"
#include "TCharacter.h"

void ATController::SetupInputComponent( )
{
    Super::SetupInputComponent( );
    
    if( InputComponent )
    {
        InputComponent->BindAxis( "Forward", this, &ATController::Forward );
        InputComponent->BindAxis( "Right", this, &ATController::Right );
        InputComponent->BindAxis( "Look", this, &ATController::YawInput );
        InputComponent->BindAxis( "Up", this, &ATController::PitchInput );
        
        InputComponent->BindAction( "LeftClick", IE_Pressed, this, &ATController::OnClick );   
    }
}

void ATController::OnClick( )
{
    UE_LOG(LogTemp, Warning, TEXT("OnClick") ) ;
}

void ATController::Forward( float A )
{
    if( GetPawn( ) == nullptr )
    {
        return;
    }
    
    if( A != 0.f )
    {
        GetPawn( )->AddMovementInput( GetPawn( )->GetActorForwardVector( ), A );
    }
}

void ATController::Right( float A )
{
    if( GetPawn( ) == nullptr )
    {
        return;
    }
    
    if( A != 0.f )
    {
        GetPawn( )->AddMovementInput( GetPawn( )->GetActorRightVector( ), A );
    }    
}

void ATController::YawInput( float A )
{
    if( GetPawn( ) == nullptr )
    {
        return;
    }
 
    GetPawn( )->AddControllerYawInput( A );
}

void ATController::PitchInput( float A )
{    
    if( GetPawn( ) == nullptr )
    {
        return;
    }
 
    GetPawn( )->AddControllerPitchInput( A );
}

Log when Left Clicking:

LogTemp:Warning: OnClick
LogTemp:Warning: OnClick
LogTemp:Warning: OnClick

Input:

109976-501536_input.png

Character:

Project You’ll have to create Visual Studio sln via right-click on .uproject → Generate Visual Studio Project files

Download: [AH501536][3]

Because I am not seeing the same issue you are, can you please explain to me or show me what you could be doing that may be causing the issue?

Thanks.

Hey,

Thanks for looking into this thoroughly. After reverting to a revision before I added the click event and re implementing it, it seems to work fine now. I’ll provide screenshots of the input settings as well as the editor preferences for clicking just in case someone else runs into this issue. Bizarre that it would just correct itself.

Could it possibly be that I had bEnableClickEvents enabled on the controller?

Anyways, thanks again for the help!