Files
MerchanTale/Source/MerchanTale/MerchanTalePlayerController.cpp
2025-10-17 00:03:43 -04:00

126 lines
4.4 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "MerchanTalePlayerController.h"
#include "GameFramework/Pawn.h"
#include "Blueprint/AIBlueprintHelperLibrary.h"
#include "NiagaraSystem.h"
#include "NiagaraFunctionLibrary.h"
#include "MerchanTaleCharacter.h"
#include "Engine/World.h"
#include "EnhancedInputComponent.h"
#include "InputActionValue.h"
#include "EnhancedInputSubsystems.h"
#include "Engine/LocalPlayer.h"
#include "MerchanTale.h"
AMerchanTalePlayerController::AMerchanTalePlayerController()
{
bIsTouch = false;
bMoveToMouseCursor = false;
// configure the controller
bShowMouseCursor = true;
DefaultMouseCursor = EMouseCursor::Default;
CachedDestination = FVector::ZeroVector;
FollowTime = 0.f;
}
void AMerchanTalePlayerController::SetupInputComponent()
{
// set up gameplay key bindings
Super::SetupInputComponent();
// Only set up input on local player controllers
if (IsLocalPlayerController())
{
// Add Input Mapping Context
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer()))
{
Subsystem->AddMappingContext(DefaultMappingContext, 0);
}
// Set up action bindings
if (UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(InputComponent))
{
// Setup mouse input events
EnhancedInputComponent->BindAction(SetDestinationClickAction, ETriggerEvent::Started, this, &AMerchanTalePlayerController::OnInputStarted);
EnhancedInputComponent->BindAction(SetDestinationClickAction, ETriggerEvent::Triggered, this, &AMerchanTalePlayerController::OnSetDestinationTriggered);
EnhancedInputComponent->BindAction(SetDestinationClickAction, ETriggerEvent::Completed, this, &AMerchanTalePlayerController::OnSetDestinationReleased);
EnhancedInputComponent->BindAction(SetDestinationClickAction, ETriggerEvent::Canceled, this, &AMerchanTalePlayerController::OnSetDestinationReleased);
// Setup touch input events
EnhancedInputComponent->BindAction(SetDestinationTouchAction, ETriggerEvent::Started, this, &AMerchanTalePlayerController::OnInputStarted);
EnhancedInputComponent->BindAction(SetDestinationTouchAction, ETriggerEvent::Triggered, this, &AMerchanTalePlayerController::OnTouchTriggered);
EnhancedInputComponent->BindAction(SetDestinationTouchAction, ETriggerEvent::Completed, this, &AMerchanTalePlayerController::OnTouchReleased);
EnhancedInputComponent->BindAction(SetDestinationTouchAction, ETriggerEvent::Canceled, this, &AMerchanTalePlayerController::OnTouchReleased);
}
else
{
UE_LOG(LogMerchanTale, Error, TEXT("'%s' Failed to find an Enhanced Input Component! This template is built to use the Enhanced Input system. If you intend to use the legacy system, then you will need to update this C++ file."), *GetNameSafe(this));
}
}
}
void AMerchanTalePlayerController::OnInputStarted()
{
StopMovement();
}
void AMerchanTalePlayerController::OnSetDestinationTriggered()
{
// We flag that the input is being pressed
FollowTime += GetWorld()->GetDeltaSeconds();
// We look for the location in the world where the player has pressed the input
FHitResult Hit;
bool bHitSuccessful = false;
if (bIsTouch)
{
bHitSuccessful = GetHitResultUnderFinger(ETouchIndex::Touch1, ECollisionChannel::ECC_Visibility, true, Hit);
}
else
{
bHitSuccessful = GetHitResultUnderCursor(ECollisionChannel::ECC_Visibility, true, Hit);
}
// If we hit a surface, cache the location
if (bHitSuccessful)
{
CachedDestination = Hit.Location;
}
// Move towards mouse pointer or touch
APawn* ControlledPawn = GetPawn();
if (ControlledPawn != nullptr)
{
FVector WorldDirection = (CachedDestination - ControlledPawn->GetActorLocation()).GetSafeNormal();
ControlledPawn->AddMovementInput(WorldDirection, 1.0, false);
}
}
void AMerchanTalePlayerController::OnSetDestinationReleased()
{
// If it was a short press
if (FollowTime <= ShortPressThreshold)
{
// We move there and spawn some particles
UAIBlueprintHelperLibrary::SimpleMoveToLocation(this, CachedDestination);
UNiagaraFunctionLibrary::SpawnSystemAtLocation(this, FXCursor, CachedDestination, FRotator::ZeroRotator, FVector(1.f, 1.f, 1.f), true, true, ENCPoolMethod::None, true);
}
FollowTime = 0.f;
}
// Triggered every frame when the input is held down
void AMerchanTalePlayerController::OnTouchTriggered()
{
bIsTouch = true;
OnSetDestinationTriggered();
}
void AMerchanTalePlayerController::OnTouchReleased()
{
bIsTouch = false;
OnSetDestinationReleased();
}