generated from amasson/UnrealEngineProject
107 lines
3.1 KiB
C++
107 lines
3.1 KiB
C++
// Amasson
|
|
|
|
|
|
#include "Components/AutoRunComponent.h"
|
|
#include "Components/SplineComponent.h"
|
|
#include "NavigationSystem.h"
|
|
#include "NavigationPath.h"
|
|
|
|
|
|
UAutoRunComponent::UAutoRunComponent()
|
|
{
|
|
PrimaryComponentTick.bCanEverTick = true;
|
|
|
|
PathSpline = CreateDefaultSubobject<USplineComponent>("PathSpline");
|
|
}
|
|
|
|
void UAutoRunComponent::SetControlledPawn(APawn* Pawn)
|
|
{
|
|
ControlledPawn = Pawn;
|
|
}
|
|
|
|
void UAutoRunComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
|
|
{
|
|
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
|
|
|
if (bAutoRunning)
|
|
if (IsValid(ControlledPawn) && IsValid(PathSpline))
|
|
{
|
|
const FVector PawnLocation = ControlledPawn->GetActorLocation();
|
|
const float ClosePointKey = PathSpline->FindInputKeyClosestToWorldLocation(PawnLocation);
|
|
const FVector LocationOnSpline = PathSpline->GetLocationAtSplineInputKey(ClosePointKey, ESplineCoordinateSpace::World);
|
|
const FVector SplineDirection = PathSpline->GetDirectionAtSplineInputKey(ClosePointKey, ESplineCoordinateSpace::World);
|
|
const FVector NextTargetPoint = PathSpline->GetLocationAtSplineInputKey(FMath::CeilToFloat(ClosePointKey + 0.5), ESplineCoordinateSpace::World);
|
|
FVector DirectionToNextTargetPoint = NextTargetPoint - PawnLocation;
|
|
|
|
DirectionToNextTargetPoint.Normalize();
|
|
|
|
ControlledPawn->AddMovementInput((SplineDirection + DirectionToNextTargetPoint) / 2);
|
|
|
|
if (ClosePointKey >= static_cast<float>(PathSpline->GetNumberOfSplinePoints()) - 1.1)
|
|
bAutoRunning = false;
|
|
|
|
}
|
|
}
|
|
|
|
void UAutoRunComponent::StopAutoRun()
|
|
{
|
|
bAutoRunning = false;
|
|
}
|
|
|
|
void UAutoRunComponent::AutoRunKeyPressed()
|
|
{
|
|
FollowTime = 0;
|
|
bAutoRunning = false;
|
|
}
|
|
|
|
void UAutoRunComponent::AutoRunKeyReleased()
|
|
{
|
|
if (!IsValid(ControlledPawn))
|
|
return;
|
|
|
|
if (FollowTime < ShortPressThreshold)
|
|
{
|
|
if (UNavigationPath* NavPath = UNavigationSystemV1::FindPathToLocationSynchronously(this, ControlledPawn->GetActorLocation(), CachedDestination))
|
|
{
|
|
if (IsValid(PathSpline))
|
|
{
|
|
PathSpline->ClearSplinePoints();
|
|
for (const FVector& PointLoc : NavPath->PathPoints)
|
|
{
|
|
PathSpline->AddSplinePoint(PointLoc, ESplineCoordinateSpace::World);
|
|
}
|
|
}
|
|
if (!NavPath->PathPoints.IsEmpty())
|
|
CachedDestination = NavPath->PathPoints[NavPath->PathPoints.Num() - 1];
|
|
OnAutoWalkBegin.Broadcast(this, CachedDestination);
|
|
bAutoRunning = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
void UAutoRunComponent::AutoRunKeyHold(float DeltaTime, const FHitResult& CursorHit)
|
|
{
|
|
FollowTime += DeltaTime;
|
|
|
|
if (CursorHit.bBlockingHit)
|
|
{
|
|
CachedDestination = CursorHit.ImpactPoint;
|
|
if (IsValid(ControlledPawn))
|
|
{
|
|
const FVector WorldDirection = (CachedDestination - ControlledPawn->GetActorLocation()).GetSafeNormal();
|
|
ControlledPawn->AddMovementInput(WorldDirection);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool UAutoRunComponent::IsAtDestination() const
|
|
{
|
|
if (!IsValid(ControlledPawn))
|
|
return false;
|
|
|
|
const float SquaredDistanceToDestination = (ControlledPawn->GetActorLocation() - CachedDestination).SquaredLength();
|
|
const float SquaredAcceptanceRadius = AutoRunAcceptanceRadius * AutoRunAcceptanceRadius;
|
|
|
|
return SquaredDistanceToDestination <= SquaredAcceptanceRadius;
|
|
}
|