Improve spline path detection
This commit is contained in:
parent
828faa777c
commit
9e5071bf84
BIN
Pawn_Unreal/Content/Characters/BP_Judy.uasset
(Stored with Git LFS)
BIN
Pawn_Unreal/Content/Characters/BP_Judy.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Pawn_Unreal/Content/Developers/maxim/NewBlueprint.uasset
(Stored with Git LFS)
BIN
Pawn_Unreal/Content/Developers/maxim/NewBlueprint.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Pawn_Unreal/Content/Maps/Dev/MAP_ControllerGym.umap
(Stored with Git LFS)
BIN
Pawn_Unreal/Content/Maps/Dev/MAP_ControllerGym.umap
(Stored with Git LFS)
Binary file not shown.
BIN
Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/7/XI/E6LKSBF268EF50PL6DUDRS.uasset
(Stored with Git LFS)
Normal file
BIN
Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/7/XI/E6LKSBF268EF50PL6DUDRS.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/B/PJ/SG13J7WCZ1GL1Q1DWQNE8E.uasset
(Stored with Git LFS)
BIN
Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/B/PJ/SG13J7WCZ1GL1Q1DWQNE8E.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/D/CW/QYYSD12YDU0PI51J52Y2HA.uasset
(Stored with Git LFS)
BIN
Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/D/CW/QYYSD12YDU0PI51J52Y2HA.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/E/9K/R7HQI0E9NM3G94LW522VPS.uasset
(Stored with Git LFS)
BIN
Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/E/9K/R7HQI0E9NM3G94LW522VPS.uasset
(Stored with Git LFS)
Binary file not shown.
@ -6,6 +6,7 @@
|
|||||||
#include "GameplayModes/PwnGameplayModeSubsystem.h"
|
#include "GameplayModes/PwnGameplayModeSubsystem.h"
|
||||||
#include "GameplayModes/Combat/PwnCombatPlatformerPath.h"
|
#include "GameplayModes/Combat/PwnCombatPlatformerPath.h"
|
||||||
#include "Kismet/KismetSystemLibrary.h"
|
#include "Kismet/KismetSystemLibrary.h"
|
||||||
|
#include "Utils/EngineUtils.h"
|
||||||
|
|
||||||
constexpr float LineTraceDistance = 10000.0f;
|
constexpr float LineTraceDistance = 10000.0f;
|
||||||
|
|
||||||
@ -102,31 +103,29 @@ bool UPwnCharacterMovementComponent::IsCustomMovementMode(const ECustomMovementM
|
|||||||
bool UPwnCharacterMovementComponent::LineTraceToGround(FHitResult& OutHit, const FVector& StartLocation, const FLinearColor& DebugColor) const {
|
bool UPwnCharacterMovementComponent::LineTraceToGround(FHitResult& OutHit, const FVector& StartLocation, const FLinearColor& DebugColor) const {
|
||||||
const FVector EndLocation = StartLocation + FVector(0.0f, 0.0f, -LineTraceDistance);
|
const FVector EndLocation = StartLocation + FVector(0.0f, 0.0f, -LineTraceDistance);
|
||||||
return UKismetSystemLibrary::LineTraceSingle(this, StartLocation, EndLocation, UEngineTypes::ConvertToTraceType(ECC_Visibility), false, TArray<AActor*>(),
|
return UKismetSystemLibrary::LineTraceSingle(this, StartLocation, EndLocation, UEngineTypes::ConvertToTraceType(ECC_Visibility), false, TArray<AActor*>(),
|
||||||
DebugColor == FLinearColor::White ? EDrawDebugTrace::None : EDrawDebugTrace::ForDuration, OutHit, true, DebugColor, FLinearColor::Green, 0.5f);
|
DebugColor == FLinearColor::White ? EDrawDebugTrace::None : EDrawDebugTrace::None, OutHit, true, DebugColor, FLinearColor::Green, 0.5f);
|
||||||
}
|
}
|
||||||
float AccumulatedTimer = 0.0f;
|
float AccumulatedTimer = 0.0f;
|
||||||
void UPwnCharacterMovementComponent::UpdateCurrentCombatPath(const bool Force, const bool UpdateLocation) {
|
void UPwnCharacterMovementComponent::UpdateCurrentCombatPath(const bool Force, const bool UpdateLocation) {
|
||||||
AccumulatedTimer += GetWorld()->GetDeltaSeconds();
|
AccumulatedTimer += GetWorld()->GetDeltaSeconds();
|
||||||
if (AccumulatedTimer < 0.3f && !Force) {
|
if (AccumulatedTimer < 0.5f && !Force) {
|
||||||
|
if (CombatPath != nullptr) {
|
||||||
|
const float ClosestInputKey = CombatPath->Spline->FindInputKeyClosestToWorldLocation(UpdatedComponent->GetComponentLocation());
|
||||||
|
CombatPath->UpdateFlattenSpline(ClosestInputKey);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AccumulatedTimer = 0.0f;
|
AccumulatedTimer = 0.0f;
|
||||||
APwnCombatPlatformerPath* OutCombatPath;
|
|
||||||
FHitResult Hit;
|
|
||||||
float ClosestInputKey = -1.0f;
|
|
||||||
if (LineTraceToGround(Hit, UpdatedComponent->GetComponentLocation(), FLinearColor::Red)) {
|
|
||||||
UE_LOG(LogTemp, Log, TEXT("Hit location : %s"), *Hit.ImpactPoint.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
APwnCombatPlatformerPath* OutCombatPath;
|
||||||
|
FVector ClosestLocation;
|
||||||
|
FHitResult Hit;
|
||||||
if (LineTraceToGround(Hit, UpdatedComponent->GetComponentLocation(), FLinearColor::Red)
|
if (LineTraceToGround(Hit, UpdatedComponent->GetComponentLocation(), FLinearColor::Red)
|
||||||
&& UPwnGameplayModeSubsystem::Get(this).FindClosestCombatPathLocation(Hit.ImpactPoint, OutCombatPath)
|
&& UPwnGameplayModeSubsystem::Get(this).FindClosestCombatPathLocation(Hit.ImpactPoint, OutCombatPath, ClosestLocation)
|
||||||
&& OutCombatPath != CombatPath) {
|
&& OutCombatPath != CombatPath) {
|
||||||
CombatPath = OutCombatPath;
|
CombatPath = OutCombatPath;
|
||||||
DotDirection = CombatPath->Reversed ? -1.0f : 1.0f;
|
DotDirection = CombatPath->Reversed ? -1.0f : 1.0f;
|
||||||
|
|
||||||
ClosestInputKey = CombatPath->Spline->FindInputKeyClosestToWorldLocation(UpdatedComponent->GetComponentLocation());
|
|
||||||
const FVector ClosestLocation = CombatPath->Spline->GetLocationAtSplineInputKey(ClosestInputKey, ESplineCoordinateSpace::World);
|
|
||||||
|
|
||||||
if (LineTraceToGround(Hit, ClosestLocation, FLinearColor::Blue)) {
|
if (LineTraceToGround(Hit, ClosestLocation, FLinearColor::Blue)) {
|
||||||
const float SplineKey = CombatPath->FlattenedSpline->FindInputKeyClosestToWorldLocation(Hit.ImpactPoint);
|
const float SplineKey = CombatPath->FlattenedSpline->FindInputKeyClosestToWorldLocation(Hit.ImpactPoint);
|
||||||
DistanceAlongSpline = CombatPath->FlattenedSpline->GetDistanceAlongSplineAtSplineInputKey(SplineKey);
|
DistanceAlongSpline = CombatPath->FlattenedSpline->GetDistanceAlongSplineAtSplineInputKey(SplineKey);
|
||||||
@ -141,10 +140,7 @@ void UPwnCharacterMovementComponent::UpdateCurrentCombatPath(const bool Force, c
|
|||||||
|
|
||||||
check(CombatPath);
|
check(CombatPath);
|
||||||
|
|
||||||
// If the combat path was the same as before, the closest input key will has not been computed
|
const float ClosestInputKey = CombatPath->Spline->FindInputKeyClosestToWorldLocation(UpdatedComponent->GetComponentLocation());
|
||||||
if (ClosestInputKey < 0.0f) {
|
|
||||||
ClosestInputKey = CombatPath->Spline->FindInputKeyClosestToWorldLocation(UpdatedComponent->GetComponentLocation());
|
|
||||||
}
|
|
||||||
CombatPath->UpdateFlattenSpline(ClosestInputKey);
|
CombatPath->UpdateFlattenSpline(ClosestInputKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,7 +392,7 @@ void UPwnCharacterMovementComponent::PhysSplineWalking(const float DeltaTime, in
|
|||||||
|
|
||||||
/* -- PAWN MODIFICATIONS -- */
|
/* -- PAWN MODIFICATIONS -- */
|
||||||
UpdateDistanceAlongSpline();
|
UpdateDistanceAlongSpline();
|
||||||
//UpdateLocationOnFlattenedSpline();
|
UpdateLocationOnFlattenedSpline();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UPwnCharacterMovementComponent::PhysSplineFalling(const float DeltaTime, int32 Iterations) {
|
void UPwnCharacterMovementComponent::PhysSplineFalling(const float DeltaTime, int32 Iterations) {
|
||||||
|
|||||||
@ -33,7 +33,7 @@ void APwnCombatPlatformerPath::UpdateFlattenSpline(const float InputKey) {
|
|||||||
|
|
||||||
FlattenedSpline->ClearSplinePoints(false);
|
FlattenedSpline->ClearSplinePoints(false);
|
||||||
|
|
||||||
const FVector FirstPointLocation = Spline->GetLocationAtSplinePoint(MinKey, ESplineCoordinateSpace::World);
|
const FVector FirstPointLocation = Spline->GetLocationAtSplinePoint(InputKey, ESplineCoordinateSpace::World);
|
||||||
const float FirstPointZ = FirstPointLocation.Z;
|
const float FirstPointZ = FirstPointLocation.Z;
|
||||||
|
|
||||||
int32 PointIndex = 0;
|
int32 PointIndex = 0;
|
||||||
|
|||||||
@ -49,30 +49,57 @@ void UPwnGameplayModeSubsystem::UnregisterCombatPath(APwnCombatPlatformerPath* C
|
|||||||
CombatPaths.Remove(CombatPath);
|
CombatPaths.Remove(CombatPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UPwnGameplayModeSubsystem::FindClosestCombatPathLocation(const FVector& Location, APwnCombatPlatformerPath*& OutCombatPath) const {
|
bool UPwnGameplayModeSubsystem::FindClosestCombatPathLocation(const FVector& Location, APwnCombatPlatformerPath*& OutCombatPath, FVector& ClosestLocation) const {
|
||||||
float ShortestDistance = FLT_MAX;
|
float BestDistanceAlongTheSpline = -1;
|
||||||
|
float ShortestZOffset = FLT_MAX;
|
||||||
APwnCombatPlatformerPath* ClosestCombatPath = nullptr;
|
APwnCombatPlatformerPath* ClosestCombatPath = nullptr;
|
||||||
|
|
||||||
|
const FVector Location2D = FVector(Location.X, Location.Y, 0.0f);
|
||||||
|
|
||||||
for (APwnCombatPlatformerPath* CombatPath : CombatPaths) {
|
for (APwnCombatPlatformerPath* CombatPath : CombatPaths) {
|
||||||
const USplineComponent* CurrentSpline = CombatPath->Spline;
|
const USplineComponent* CurrentSpline = CombatPath->Spline;
|
||||||
|
CombatPath->UpdateFlattenSpline(CombatPath->Spline->FindInputKeyClosestToWorldLocation(Location));
|
||||||
|
|
||||||
const float CurrentKey = CurrentSpline->FindInputKeyClosestToWorldLocation(Location);
|
const FVector FlattenedLocation = CombatPath->FlattenedSpline->FindLocationClosestToWorldLocation(Location, ESplineCoordinateSpace::World);
|
||||||
FVector CurrentLocation = CurrentSpline->GetLocationAtSplineInputKey(CurrentKey, ESplineCoordinateSpace::World);
|
|
||||||
if (CurrentLocation.Z < Location.Z) {
|
const float CurrentKey = CurrentSpline->FindInputKeyClosestToWorldLocation(FlattenedLocation);
|
||||||
|
const float CurrentDistance = CurrentSpline->GetDistanceAlongSplineAtSplineInputKey(CurrentKey);
|
||||||
|
|
||||||
|
float BestDistance = -1;
|
||||||
|
float ShortestDistanceForThisPath = FLT_MAX;
|
||||||
|
|
||||||
|
for (int i = -700; i <= 700; i += 5) {
|
||||||
|
const float SubStepDistance = CurrentDistance + i;
|
||||||
|
const FVector SubStepLocation = CurrentSpline->GetLocationAtDistanceAlongSpline(SubStepDistance, ESplineCoordinateSpace::World);
|
||||||
|
if (SubStepLocation.Z < Location.Z) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
FVector SubStepLocation2D = FVector(SubStepLocation.X, SubStepLocation.Y, 0.0f);
|
||||||
|
const float Distance = FVector::DistSquared(Location2D, SubStepLocation2D);
|
||||||
|
if (Distance < ShortestDistanceForThisPath) {
|
||||||
|
ShortestDistanceForThisPath = Distance;
|
||||||
|
BestDistance = SubStepDistance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BestDistance < 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const float CurrentDistance = FVector::DistSquared(Location, CurrentLocation);
|
|
||||||
if (CurrentDistance >= ShortestDistance) {
|
const FVector BestLocation = CurrentSpline->GetLocationAtDistanceAlongSpline(BestDistance, ESplineCoordinateSpace::World);
|
||||||
continue;
|
|
||||||
|
const float ZOffset = BestLocation.Z - Location.Z;
|
||||||
|
if (ZOffset < ShortestZOffset) {
|
||||||
|
ClosestCombatPath = CombatPath;
|
||||||
|
BestDistanceAlongTheSpline = BestDistance;
|
||||||
|
ShortestZOffset = ZOffset;
|
||||||
}
|
}
|
||||||
ShortestDistance = CurrentDistance;
|
|
||||||
ClosestCombatPath = CombatPath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ClosestCombatPath != nullptr) {
|
if (ClosestCombatPath != nullptr) {
|
||||||
OutCombatPath = ClosestCombatPath;
|
OutCombatPath = ClosestCombatPath;
|
||||||
|
ClosestLocation = OutCombatPath->Spline->GetLocationAtDistanceAlongSpline(BestDistanceAlongTheSpline, ESplineCoordinateSpace::World);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
PRINT_STRING_RED("Aie");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,7 +44,7 @@ public:
|
|||||||
void UnregisterCombatPath(APwnCombatPlatformerPath* CombatPath);
|
void UnregisterCombatPath(APwnCombatPlatformerPath* CombatPath);
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable)
|
UFUNCTION(BlueprintCallable)
|
||||||
bool FindClosestCombatPathLocation(const FVector& Location, APwnCombatPlatformerPath*& OutCombatPath) const;
|
bool FindClosestCombatPathLocation(const FVector& Location, APwnCombatPlatformerPath*& OutCombatPath, FVector& ClosestLocation) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UPROPERTY(BlueprintAssignable)
|
UPROPERTY(BlueprintAssignable)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user