From 9e5071bf84ce569745ce90d8e870e9ebc14cdd0c Mon Sep 17 00:00:00 2001 From: Maxime Date: Sat, 25 Nov 2023 22:33:22 +0100 Subject: [PATCH] Improve spline path detection --- Pawn_Unreal/Content/Characters/BP_Judy.uasset | 4 +- .../Developers/maxim/NewBlueprint.uasset | 3 -- .../Content/Maps/Dev/MAP_ControllerGym.umap | 4 +- .../7/XI/E6LKSBF268EF50PL6DUDRS.uasset | 3 ++ .../B/PJ/SG13J7WCZ1GL1Q1DWQNE8E.uasset | 4 +- .../D/CW/QYYSD12YDU0PI51J52Y2HA.uasset | 2 +- .../E/9K/R7HQI0E9NM3G94LW522VPS.uasset | 3 -- .../PwnCharacterMovementComponent.cpp | 28 +++++------ .../Combat/PwnCombatPlatformerPath.cpp | 2 +- .../PwnGameplayModeSubsystem.cpp | 49 ++++++++++++++----- .../GameplayModes/PwnGameplayModeSubsystem.h | 2 +- 11 files changed, 62 insertions(+), 42 deletions(-) delete mode 100644 Pawn_Unreal/Content/Developers/maxim/NewBlueprint.uasset create mode 100644 Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/7/XI/E6LKSBF268EF50PL6DUDRS.uasset delete mode 100644 Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/E/9K/R7HQI0E9NM3G94LW522VPS.uasset diff --git a/Pawn_Unreal/Content/Characters/BP_Judy.uasset b/Pawn_Unreal/Content/Characters/BP_Judy.uasset index 17341d7..b06a95a 100644 --- a/Pawn_Unreal/Content/Characters/BP_Judy.uasset +++ b/Pawn_Unreal/Content/Characters/BP_Judy.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e823faf6a9b291aba6b45d09176f6aeb12ee86c5df400ec81243f4e450b21d39 -size 265412 +oid sha256:f198877381ae6db83db9e1998e77df6ca13aecd5e547ed8827fd891e0eb632bb +size 184698 diff --git a/Pawn_Unreal/Content/Developers/maxim/NewBlueprint.uasset b/Pawn_Unreal/Content/Developers/maxim/NewBlueprint.uasset deleted file mode 100644 index 5bb9147..0000000 --- a/Pawn_Unreal/Content/Developers/maxim/NewBlueprint.uasset +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e58f627a164215351808a5bca99b151483863d813b48c529cfe79538d638b002 -size 27712 diff --git a/Pawn_Unreal/Content/Maps/Dev/MAP_ControllerGym.umap b/Pawn_Unreal/Content/Maps/Dev/MAP_ControllerGym.umap index df9bbdb..de3db5a 100644 --- a/Pawn_Unreal/Content/Maps/Dev/MAP_ControllerGym.umap +++ b/Pawn_Unreal/Content/Maps/Dev/MAP_ControllerGym.umap @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cdc0c4c7ede19aa393adaf5dc7f092ccd3abd90d11ae815300939c5eac828920 -size 735057 +oid sha256:ed1c9780839b00dd0690918fff90f1c6746f7afa1b7bd56ccb199828590438c9 +size 740111 diff --git a/Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/7/XI/E6LKSBF268EF50PL6DUDRS.uasset b/Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/7/XI/E6LKSBF268EF50PL6DUDRS.uasset new file mode 100644 index 0000000..7c16391 --- /dev/null +++ b/Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/7/XI/E6LKSBF268EF50PL6DUDRS.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7baa2c7b38e79b3d17ab97e229140f0baea4887886f25090699b47c0c517a23 +size 266958 diff --git a/Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/B/PJ/SG13J7WCZ1GL1Q1DWQNE8E.uasset b/Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/B/PJ/SG13J7WCZ1GL1Q1DWQNE8E.uasset index bd47d19..0aeb431 100644 --- a/Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/B/PJ/SG13J7WCZ1GL1Q1DWQNE8E.uasset +++ b/Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/B/PJ/SG13J7WCZ1GL1Q1DWQNE8E.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:893fa142a08b01557d8d90f0a87d9cffa6bec9a4cf5e642f870c65b1f4c3c3e6 -size 75333 +oid sha256:89b093b7ef85627ae9b90d9e28cb99ef77f16f1c15e82f88f4176627a9561fad +size 92748 diff --git a/Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/D/CW/QYYSD12YDU0PI51J52Y2HA.uasset b/Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/D/CW/QYYSD12YDU0PI51J52Y2HA.uasset index 3d0bf3d..537b90a 100644 --- a/Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/D/CW/QYYSD12YDU0PI51J52Y2HA.uasset +++ b/Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/D/CW/QYYSD12YDU0PI51J52Y2HA.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cb434dd91253050791872244219180b21f2e0e9e19258ec0704539aa21c57dc7 +oid sha256:73cc0f31621336af7879c3b41157a46a37f8f9af3467615190f32102472f00bf size 4450 diff --git a/Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/E/9K/R7HQI0E9NM3G94LW522VPS.uasset b/Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/E/9K/R7HQI0E9NM3G94LW522VPS.uasset deleted file mode 100644 index 2823623..0000000 --- a/Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/E/9K/R7HQI0E9NM3G94LW522VPS.uasset +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e2a5c54375c8d6daa20cf68cbad330fa3194e7de05d853c415a3730f52daf51a -size 266884 diff --git a/Pawn_Unreal/Source/Pawn/Private/Characters/PwnCharacterMovementComponent.cpp b/Pawn_Unreal/Source/Pawn/Private/Characters/PwnCharacterMovementComponent.cpp index a2e3e9d..7eee12f 100644 --- a/Pawn_Unreal/Source/Pawn/Private/Characters/PwnCharacterMovementComponent.cpp +++ b/Pawn_Unreal/Source/Pawn/Private/Characters/PwnCharacterMovementComponent.cpp @@ -6,6 +6,7 @@ #include "GameplayModes/PwnGameplayModeSubsystem.h" #include "GameplayModes/Combat/PwnCombatPlatformerPath.h" #include "Kismet/KismetSystemLibrary.h" +#include "Utils/EngineUtils.h" 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 { const FVector EndLocation = StartLocation + FVector(0.0f, 0.0f, -LineTraceDistance); return UKismetSystemLibrary::LineTraceSingle(this, StartLocation, EndLocation, UEngineTypes::ConvertToTraceType(ECC_Visibility), false, TArray(), - 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; void UPwnCharacterMovementComponent::UpdateCurrentCombatPath(const bool Force, const bool UpdateLocation) { 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; } AccumulatedTimer = 0.0f; + APwnCombatPlatformerPath* OutCombatPath; + FVector ClosestLocation; FHitResult Hit; - float ClosestInputKey = -1.0f; - if (LineTraceToGround(Hit, UpdatedComponent->GetComponentLocation(), FLinearColor::Red)) { - UE_LOG(LogTemp, Log, TEXT("Hit location : %s"), *Hit.ImpactPoint.ToString()); - } - if (LineTraceToGround(Hit, UpdatedComponent->GetComponentLocation(), FLinearColor::Red) - && UPwnGameplayModeSubsystem::Get(this).FindClosestCombatPathLocation(Hit.ImpactPoint, OutCombatPath) + && UPwnGameplayModeSubsystem::Get(this).FindClosestCombatPathLocation(Hit.ImpactPoint, OutCombatPath, ClosestLocation) && OutCombatPath != CombatPath) { CombatPath = OutCombatPath; 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)) { const float SplineKey = CombatPath->FlattenedSpline->FindInputKeyClosestToWorldLocation(Hit.ImpactPoint); DistanceAlongSpline = CombatPath->FlattenedSpline->GetDistanceAlongSplineAtSplineInputKey(SplineKey); @@ -141,10 +140,7 @@ void UPwnCharacterMovementComponent::UpdateCurrentCombatPath(const bool Force, c check(CombatPath); - // If the combat path was the same as before, the closest input key will has not been computed - if (ClosestInputKey < 0.0f) { - ClosestInputKey = CombatPath->Spline->FindInputKeyClosestToWorldLocation(UpdatedComponent->GetComponentLocation()); - } + const float ClosestInputKey = CombatPath->Spline->FindInputKeyClosestToWorldLocation(UpdatedComponent->GetComponentLocation()); CombatPath->UpdateFlattenSpline(ClosestInputKey); } @@ -396,7 +392,7 @@ void UPwnCharacterMovementComponent::PhysSplineWalking(const float DeltaTime, in /* -- PAWN MODIFICATIONS -- */ UpdateDistanceAlongSpline(); - //UpdateLocationOnFlattenedSpline(); + UpdateLocationOnFlattenedSpline(); } void UPwnCharacterMovementComponent::PhysSplineFalling(const float DeltaTime, int32 Iterations) { diff --git a/Pawn_Unreal/Source/Pawn/Private/GameplayModes/Combat/PwnCombatPlatformerPath.cpp b/Pawn_Unreal/Source/Pawn/Private/GameplayModes/Combat/PwnCombatPlatformerPath.cpp index 072bde4..9974a51 100644 --- a/Pawn_Unreal/Source/Pawn/Private/GameplayModes/Combat/PwnCombatPlatformerPath.cpp +++ b/Pawn_Unreal/Source/Pawn/Private/GameplayModes/Combat/PwnCombatPlatformerPath.cpp @@ -33,7 +33,7 @@ void APwnCombatPlatformerPath::UpdateFlattenSpline(const float InputKey) { FlattenedSpline->ClearSplinePoints(false); - const FVector FirstPointLocation = Spline->GetLocationAtSplinePoint(MinKey, ESplineCoordinateSpace::World); + const FVector FirstPointLocation = Spline->GetLocationAtSplinePoint(InputKey, ESplineCoordinateSpace::World); const float FirstPointZ = FirstPointLocation.Z; int32 PointIndex = 0; diff --git a/Pawn_Unreal/Source/Pawn/Private/GameplayModes/PwnGameplayModeSubsystem.cpp b/Pawn_Unreal/Source/Pawn/Private/GameplayModes/PwnGameplayModeSubsystem.cpp index b649aef..e185f6e 100644 --- a/Pawn_Unreal/Source/Pawn/Private/GameplayModes/PwnGameplayModeSubsystem.cpp +++ b/Pawn_Unreal/Source/Pawn/Private/GameplayModes/PwnGameplayModeSubsystem.cpp @@ -49,30 +49,57 @@ void UPwnGameplayModeSubsystem::UnregisterCombatPath(APwnCombatPlatformerPath* C CombatPaths.Remove(CombatPath); } -bool UPwnGameplayModeSubsystem::FindClosestCombatPathLocation(const FVector& Location, APwnCombatPlatformerPath*& OutCombatPath) const { - float ShortestDistance = FLT_MAX; +bool UPwnGameplayModeSubsystem::FindClosestCombatPathLocation(const FVector& Location, APwnCombatPlatformerPath*& OutCombatPath, FVector& ClosestLocation) const { + float BestDistanceAlongTheSpline = -1; + float ShortestZOffset = FLT_MAX; APwnCombatPlatformerPath* ClosestCombatPath = nullptr; + const FVector Location2D = FVector(Location.X, Location.Y, 0.0f); + for (APwnCombatPlatformerPath* CombatPath : CombatPaths) { const USplineComponent* CurrentSpline = CombatPath->Spline; + CombatPath->UpdateFlattenSpline(CombatPath->Spline->FindInputKeyClosestToWorldLocation(Location)); - const float CurrentKey = CurrentSpline->FindInputKeyClosestToWorldLocation(Location); - FVector CurrentLocation = CurrentSpline->GetLocationAtSplineInputKey(CurrentKey, ESplineCoordinateSpace::World); - if (CurrentLocation.Z < Location.Z) { + const FVector FlattenedLocation = CombatPath->FlattenedSpline->FindLocationClosestToWorldLocation(Location, ESplineCoordinateSpace::World); + + 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; } - const float CurrentDistance = FVector::DistSquared(Location, CurrentLocation); - if (CurrentDistance >= ShortestDistance) { - continue; + + const FVector BestLocation = CurrentSpline->GetLocationAtDistanceAlongSpline(BestDistance, ESplineCoordinateSpace::World); + + const float ZOffset = BestLocation.Z - Location.Z; + if (ZOffset < ShortestZOffset) { + ClosestCombatPath = CombatPath; + BestDistanceAlongTheSpline = BestDistance; + ShortestZOffset = ZOffset; } - ShortestDistance = CurrentDistance; - ClosestCombatPath = CombatPath; } if (ClosestCombatPath != nullptr) { OutCombatPath = ClosestCombatPath; + ClosestLocation = OutCombatPath->Spline->GetLocationAtDistanceAlongSpline(BestDistanceAlongTheSpline, ESplineCoordinateSpace::World); return true; } - PRINT_STRING_RED("Aie"); return false; } diff --git a/Pawn_Unreal/Source/Pawn/Public/GameplayModes/PwnGameplayModeSubsystem.h b/Pawn_Unreal/Source/Pawn/Public/GameplayModes/PwnGameplayModeSubsystem.h index 6b01140..2440f8c 100644 --- a/Pawn_Unreal/Source/Pawn/Public/GameplayModes/PwnGameplayModeSubsystem.h +++ b/Pawn_Unreal/Source/Pawn/Public/GameplayModes/PwnGameplayModeSubsystem.h @@ -44,7 +44,7 @@ public: void UnregisterCombatPath(APwnCombatPlatformerPath* CombatPath); UFUNCTION(BlueprintCallable) - bool FindClosestCombatPathLocation(const FVector& Location, APwnCombatPlatformerPath*& OutCombatPath) const; + bool FindClosestCombatPathLocation(const FVector& Location, APwnCombatPlatformerPath*& OutCombatPath, FVector& ClosestLocation) const; public: UPROPERTY(BlueprintAssignable)