Add Flatten Spline into Combat Platformer Path
This commit is contained in:
parent
29fd695a03
commit
028e228c8f
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/Core/GM_MainGameMode.uasset
(Stored with Git LFS)
BIN
Pawn_Unreal/Content/Core/GM_MainGameMode.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Pawn_Unreal/Content/Input/BP_MainPlayerController.uasset
(Stored with Git LFS)
BIN
Pawn_Unreal/Content/Input/BP_MainPlayerController.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Pawn_Unreal/Content/Systems/Camera/BP_MainCameraManager.uasset
(Stored with Git LFS)
BIN
Pawn_Unreal/Content/Systems/Camera/BP_MainCameraManager.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Pawn_Unreal/Content/Systems/Modes/BPC_GameplayModeNotifier.uasset
(Stored with Git LFS)
BIN
Pawn_Unreal/Content/Systems/Modes/BPC_GameplayModeNotifier.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Pawn_Unreal/Content/Systems/Modes/Combat/BP_CombatPlatformerPath.uasset
(Stored with Git LFS)
BIN
Pawn_Unreal/Content/Systems/Modes/Combat/BP_CombatPlatformerPath.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Pawn_Unreal/Content/Systems/Modes/E_GameplayMode.uasset
(Stored with Git LFS)
BIN
Pawn_Unreal/Content/Systems/Modes/E_GameplayMode.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/3/ZX/V7QFRP3DMWRT8NZCJQYVRB.uasset
(Stored with Git LFS)
BIN
Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/3/ZX/V7QFRP3DMWRT8NZCJQYVRB.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/9/RQ/JYNZEWOG6SXNE3HGUCSZIE.uasset
(Stored with Git LFS)
BIN
Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/9/RQ/JYNZEWOG6SXNE3HGUCSZIE.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/C/6U/C2O2TW7RAVDUQGZS7QLKMX.uasset
(Stored with Git LFS)
BIN
Pawn_Unreal/Content/__ExternalActors__/Maps/Dev/MAP_ControllerGym/C/6U/C2O2TW7RAVDUQGZS7QLKMX.uasset
(Stored with Git LFS)
Binary file not shown.
@ -1,6 +1,7 @@
|
|||||||
#include "Characters/PwnCharacterMovementComponent.h"
|
#include "Characters/PwnCharacterMovementComponent.h"
|
||||||
|
|
||||||
#include "Characters/PwnCharacterBase.h"
|
#include "Characters/PwnCharacterBase.h"
|
||||||
|
#include "Components/CapsuleComponent.h"
|
||||||
#include "Components/SplineComponent.h"
|
#include "Components/SplineComponent.h"
|
||||||
#include "GameplayModes/PwnGameplayModeSubsystem.h"
|
#include "GameplayModes/PwnGameplayModeSubsystem.h"
|
||||||
#include "GameplayModes/Combat/PwnCombatPlatformerPath.h"
|
#include "GameplayModes/Combat/PwnCombatPlatformerPath.h"
|
||||||
@ -86,16 +87,24 @@ void UPwnCharacterMovementComponent::EnterSplineFollowMode() {
|
|||||||
const UPwnGameplayModeSubsystem* Subsystem = GetWorld()->GetSubsystem<UPwnGameplayModeSubsystem>();
|
const UPwnGameplayModeSubsystem* Subsystem = GetWorld()->GetSubsystem<UPwnGameplayModeSubsystem>();
|
||||||
check(Subsystem);
|
check(Subsystem);
|
||||||
|
|
||||||
FVector OutLocation;
|
|
||||||
APwnCombatPlatformerPath* OutCombatPath;
|
APwnCombatPlatformerPath* OutCombatPath;
|
||||||
float OutDistanceAloneSpline;
|
if (Subsystem->FindClosestCombatPathLocation(UpdatedComponent->GetComponentLocation(), OutCombatPath)) {
|
||||||
if (Subsystem->FindClosestCombatPathLocation(UpdatedComponent->GetComponentLocation(), OutLocation, OutCombatPath, OutDistanceAloneSpline)) {
|
|
||||||
DistanceAlongSpline = OutDistanceAloneSpline;
|
|
||||||
CombatPath = OutCombatPath;
|
CombatPath = OutCombatPath;
|
||||||
DotDirection = CombatPath->Reversed ? -1.0f : 1.0f;
|
DotDirection = CombatPath->Reversed ? -1.0f : 1.0f;
|
||||||
FVector TargetLocation = CombatPath->Spline->GetLocationAtDistanceAlongSpline(DistanceAlongSpline, ESplineCoordinateSpace::World);
|
|
||||||
TargetLocation.Z = UpdatedComponent->GetComponentLocation().Z;
|
float ClosestInputKey = CombatPath->Spline->FindInputKeyClosestToWorldLocation(UpdatedComponent->GetComponentLocation());
|
||||||
UpdatedComponent->SetWorldLocation(TargetLocation);
|
FVector ClosestLocation = CombatPath->Spline->GetLocationAtSplineInputKey(ClosestInputKey, ESplineCoordinateSpace::World);
|
||||||
|
|
||||||
|
FHitResult Hit;
|
||||||
|
if (GetWorld()->LineTraceSingleByChannel(Hit, ClosestLocation, ClosestLocation + FVector(0.0f, 0.0f, -10000.0f),
|
||||||
|
ECC_Visibility, IGNORE_OWNER_PARAMS)) {
|
||||||
|
const float SplineKey = CombatPath->FlattenSpline->FindInputKeyClosestToWorldLocation(Hit.ImpactPoint);
|
||||||
|
DistanceAlongSpline = CombatPath->FlattenSpline->GetDistanceAlongSplineAtSplineInputKey(SplineKey);
|
||||||
|
|
||||||
|
ClosestLocation.Z += CharacterOwner->GetCapsuleComponent()->GetScaledCapsuleHalfHeight();
|
||||||
|
UpdatedComponent->SetWorldLocation(ClosestLocation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +118,7 @@ bool UPwnCharacterMovementComponent::IsCustomMovementMode(const ECustomMovementM
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UPwnCharacterMovementComponent::RecomputeTangentAndAcceleration() {
|
void UPwnCharacterMovementComponent::RecomputeTangentAndAcceleration() {
|
||||||
Tangent2D = CombatPath->Spline->GetTangentAtDistanceAlongSpline(DistanceAlongSpline, ESplineCoordinateSpace::World).GetSafeNormal2D();
|
Tangent2D = CombatPath->FlattenSpline->GetTangentAtDistanceAlongSpline(DistanceAlongSpline, ESplineCoordinateSpace::World).GetSafeNormal2D();
|
||||||
// Recalculate acceleration so the input is relative to the spline
|
// Recalculate acceleration so the input is relative to the spline
|
||||||
Acceleration = Tangent2D * Acceleration.Size2D() * FMath::Sign(Acceleration.X) * DotDirection;
|
Acceleration = Tangent2D * Acceleration.Size2D() * FMath::Sign(Acceleration.X) * DotDirection;
|
||||||
}
|
}
|
||||||
@ -127,9 +136,9 @@ void UPwnCharacterMovementComponent::UpdatePawnVelocity(const float TimeTick) {
|
|||||||
VelocityDirection = FMath::Sign(VelocityDirection); // -1, 0 or 1
|
VelocityDirection = FMath::Sign(VelocityDirection); // -1, 0 or 1
|
||||||
|
|
||||||
float NewDistanceAlongSpline = DistanceAlongSpline + VelocityDirection * VelocitySize2D * TimeTick;
|
float NewDistanceAlongSpline = DistanceAlongSpline + VelocityDirection * VelocitySize2D * TimeTick;
|
||||||
NewDistanceAlongSpline = FMath::Clamp(NewDistanceAlongSpline, 0.0f, CombatPath->Spline->GetSplineLength());
|
NewDistanceAlongSpline = FMath::Clamp(NewDistanceAlongSpline, 0.0f, CombatPath->FlattenSpline->GetSplineLength());
|
||||||
|
|
||||||
FVector TargetLocation = CombatPath->Spline->GetLocationAtDistanceAlongSpline(NewDistanceAlongSpline, ESplineCoordinateSpace::World);
|
FVector TargetLocation = CombatPath->FlattenSpline->GetLocationAtDistanceAlongSpline(NewDistanceAlongSpline, ESplineCoordinateSpace::World);
|
||||||
TargetLocation.Z = OldLocation.Z;
|
TargetLocation.Z = OldLocation.Z;
|
||||||
|
|
||||||
const FVector Direction = (TargetLocation - OldLocation).GetSafeNormal2D();
|
const FVector Direction = (TargetLocation - OldLocation).GetSafeNormal2D();
|
||||||
@ -142,18 +151,16 @@ void UPwnCharacterMovementComponent::UpdatePawnVelocity(const float TimeTick) {
|
|||||||
void UPwnCharacterMovementComponent::UpdateDistanceAlongSplineAndLocation() {
|
void UPwnCharacterMovementComponent::UpdateDistanceAlongSplineAndLocation() {
|
||||||
// Maintain coherent distance along spline with location
|
// Maintain coherent distance along spline with location
|
||||||
FHitResult Hit;
|
FHitResult Hit;
|
||||||
FCollisionQueryParams QueryParams;
|
|
||||||
QueryParams.AddIgnoredActor(GetOwner());
|
|
||||||
if (GetWorld()->LineTraceSingleByChannel(Hit, UpdatedComponent->GetComponentLocation(),
|
if (GetWorld()->LineTraceSingleByChannel(Hit, UpdatedComponent->GetComponentLocation(),
|
||||||
UpdatedComponent->GetComponentLocation() + FVector(0.0f, 0.0f, -10000.0f),
|
UpdatedComponent->GetComponentLocation() + FVector(0.0f, 0.0f, -10000.0f),
|
||||||
ECC_Visibility, QueryParams)) {
|
ECC_Visibility, IGNORE_OWNER_PARAMS)) {
|
||||||
|
|
||||||
FVector ImpactPoint = Hit.ImpactPoint;
|
FVector ImpactPoint = Hit.ImpactPoint;
|
||||||
const float InputKey = CombatPath->Spline->FindInputKeyClosestToWorldLocation(ImpactPoint);
|
const float InputKey = CombatPath->FlattenSpline->FindInputKeyClosestToWorldLocation(ImpactPoint);
|
||||||
DistanceAlongSpline = CombatPath->Spline->GetDistanceAlongSplineAtSplineInputKey(InputKey);
|
DistanceAlongSpline = CombatPath->FlattenSpline->GetDistanceAlongSplineAtSplineInputKey(InputKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
FVector TargetLocation = CombatPath->Spline->GetLocationAtDistanceAlongSpline(DistanceAlongSpline, ESplineCoordinateSpace::World);
|
FVector TargetLocation = CombatPath->FlattenSpline->GetLocationAtDistanceAlongSpline(DistanceAlongSpline, ESplineCoordinateSpace::World);
|
||||||
TargetLocation.Z = UpdatedComponent->GetComponentLocation().Z;
|
TargetLocation.Z = UpdatedComponent->GetComponentLocation().Z;
|
||||||
UpdatedComponent->SetWorldLocation(TargetLocation);
|
UpdatedComponent->SetWorldLocation(TargetLocation);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@ APwnCombatPlatformerPath::APwnCombatPlatformerPath() {
|
|||||||
PrimaryActorTick.bCanEverTick = false;
|
PrimaryActorTick.bCanEverTick = false;
|
||||||
|
|
||||||
Spline = CreateDefaultSubobject<USplineComponent>(TEXT("Spline"));
|
Spline = CreateDefaultSubobject<USplineComponent>(TEXT("Spline"));
|
||||||
|
Spline->ReparamStepsPerSegment = 100.0f;
|
||||||
SetRootComponent(Spline);
|
SetRootComponent(Spline);
|
||||||
|
|
||||||
#if WITH_EDITORONLY_DATA
|
#if WITH_EDITORONLY_DATA
|
||||||
@ -20,24 +21,29 @@ void APwnCombatPlatformerPath::BeginPlay() {
|
|||||||
check(Subsystem);
|
check(Subsystem);
|
||||||
Subsystem->RegisterCombatPath(this);
|
Subsystem->RegisterCombatPath(this);
|
||||||
|
|
||||||
|
FlattenSpline = NewObject<USplineComponent>(this, TEXT("FlattenSpline"));
|
||||||
|
FlattenSpline->SetClosedLoop(Spline->IsClosedLoop(), false);
|
||||||
|
FlattenSpline->ReparamStepsPerSegment = Spline->ReparamStepsPerSegment;
|
||||||
|
FlattenSpline->ClearSplinePoints(false);
|
||||||
|
|
||||||
const FVector FirstPointLocation = Spline->GetLocationAtSplinePoint(0, ESplineCoordinateSpace::World);
|
const FVector FirstPointLocation = Spline->GetLocationAtSplinePoint(0, ESplineCoordinateSpace::World);
|
||||||
float FirstPointZ = FirstPointLocation.Z;
|
const float FirstPointZ = FirstPointLocation.Z;
|
||||||
|
|
||||||
const int32 PointsCount = Spline->GetNumberOfSplinePoints();
|
const int32 PointsCount = Spline->GetNumberOfSplinePoints();
|
||||||
for (int i = 0; i < PointsCount; ++i) {
|
for (int i = 0; i < PointsCount; ++i) {
|
||||||
FVector NewLocation = Spline->GetLocationAtSplinePoint(i, ESplineCoordinateSpace::World);
|
FVector NewLocation = Spline->GetLocationAtSplinePoint(i, ESplineCoordinateSpace::World);
|
||||||
NewLocation.Z = FirstPointZ;
|
NewLocation.Z = FirstPointZ;
|
||||||
Spline->SetLocationAtSplinePoint(i, NewLocation, ESplineCoordinateSpace::World, false);
|
FlattenSpline->AddSplinePoint(NewLocation, ESplineCoordinateSpace::World, false);
|
||||||
|
|
||||||
FVector ArriveTangent = Spline->GetArriveTangentAtSplinePoint(i, ESplineCoordinateSpace::World);
|
FVector ArriveTangent = Spline->GetArriveTangentAtSplinePoint(i, ESplineCoordinateSpace::World);
|
||||||
FVector LeaveTangent = Spline->GetLeaveTangentAtSplinePoint(i, ESplineCoordinateSpace::World);
|
FVector LeaveTangent = Spline->GetLeaveTangentAtSplinePoint(i, ESplineCoordinateSpace::World);
|
||||||
|
|
||||||
ArriveTangent.Z = 0;
|
ArriveTangent.Z = 0;
|
||||||
LeaveTangent.Z = 0;
|
LeaveTangent.Z = 0;
|
||||||
Spline->SetTangentsAtSplinePoint(i, ArriveTangent, LeaveTangent, ESplineCoordinateSpace::World, false);
|
FlattenSpline->SetTangentsAtSplinePoint(i, ArriveTangent, LeaveTangent, ESplineCoordinateSpace::World, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Spline->UpdateSpline();
|
FlattenSpline->UpdateSpline();
|
||||||
|
|
||||||
Super::BeginPlay();
|
Super::BeginPlay();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,11 +41,8 @@ void UPwnGameplayModeSubsystem::UnregisterCombatPath(APwnCombatPlatformerPath* C
|
|||||||
CombatPaths.Remove(CombatPath);
|
CombatPaths.Remove(CombatPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UPwnGameplayModeSubsystem::FindClosestCombatPathLocation(const FVector& Location, FVector& OutCombatPathLocation,
|
bool UPwnGameplayModeSubsystem::FindClosestCombatPathLocation(const FVector& Location, APwnCombatPlatformerPath*& OutCombatPath) const {
|
||||||
APwnCombatPlatformerPath*& OutCombatPath, float& OutDistanceAlongSpline) const {
|
|
||||||
float ShortestDistance = FLT_MAX;
|
float ShortestDistance = FLT_MAX;
|
||||||
float ClosestKey = 0.0f;
|
|
||||||
FVector ClosestLocation = FVector::ZeroVector;
|
|
||||||
APwnCombatPlatformerPath* ClosestCombatPath = nullptr;
|
APwnCombatPlatformerPath* ClosestCombatPath = nullptr;
|
||||||
bool Found = false;
|
bool Found = false;
|
||||||
|
|
||||||
@ -57,17 +54,13 @@ bool UPwnGameplayModeSubsystem::FindClosestCombatPathLocation(const FVector& Loc
|
|||||||
const float CurrentDistance = FVector::DistSquared(Location, CurrentLocation);
|
const float CurrentDistance = FVector::DistSquared(Location, CurrentLocation);
|
||||||
if (CurrentDistance < ShortestDistance) {
|
if (CurrentDistance < ShortestDistance) {
|
||||||
ShortestDistance = CurrentDistance;
|
ShortestDistance = CurrentDistance;
|
||||||
ClosestKey = CurrentKey;
|
|
||||||
ClosestLocation = CurrentLocation;
|
|
||||||
ClosestCombatPath = CombatPath;
|
ClosestCombatPath = CombatPath;
|
||||||
Found = true;
|
Found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Found) {
|
if (Found) {
|
||||||
OutCombatPathLocation = ClosestLocation;
|
|
||||||
OutCombatPath = ClosestCombatPath;
|
OutCombatPath = ClosestCombatPath;
|
||||||
OutDistanceAlongSpline = OutCombatPath->Spline->GetDistanceAlongSplineAtSplineInputKey(ClosestKey);
|
|
||||||
}
|
}
|
||||||
return Found;
|
return Found;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,7 +19,7 @@ protected:
|
|||||||
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Components")
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Components")
|
||||||
TObjectPtr<USplineComponent> Spline;
|
TObjectPtr<USplineComponent> Spline;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Combat Platformer Path")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Combat Platformer Path")
|
||||||
@ -27,4 +27,7 @@ public:
|
|||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Combat Platformer Path")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Combat Platformer Path")
|
||||||
bool SwapCamera;
|
bool SwapCamera;
|
||||||
|
|
||||||
|
UPROPERTY(Transient, BlueprintReadOnly)
|
||||||
|
TObjectPtr<USplineComponent> FlattenSpline;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -41,9 +41,8 @@ public:
|
|||||||
UFUNCTION()
|
UFUNCTION()
|
||||||
void UnregisterCombatPath(APwnCombatPlatformerPath* CombatPath);
|
void UnregisterCombatPath(APwnCombatPlatformerPath* CombatPath);
|
||||||
|
|
||||||
UFUNCTION()
|
UFUNCTION(BlueprintCallable)
|
||||||
bool FindClosestCombatPathLocation(const FVector& Location, FVector& OutCombatPathLocation, APwnCombatPlatformerPath*& OutCombatPath,
|
bool FindClosestCombatPathLocation(const FVector& Location, APwnCombatPlatformerPath*& OutCombatPath) const;
|
||||||
float& OutDistanceAlongSpline) const;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UPROPERTY(BlueprintAssignable)
|
UPROPERTY(BlueprintAssignable)
|
||||||
|
|||||||
@ -10,3 +10,12 @@
|
|||||||
|
|
||||||
#define BOOL_TO_TEXT(Bool) ((Bool) ? TEXT("True") : TEXT("False"))
|
#define BOOL_TO_TEXT(Bool) ((Bool) ? TEXT("True") : TEXT("False"))
|
||||||
#define BOOL_TO_STR(Bool) ((Bool) ? "True" : "False")
|
#define BOOL_TO_STR(Bool) ((Bool) ? "True" : "False")
|
||||||
|
|
||||||
|
#define IGNORE_OWNER_PARAMS GetIgnoreActorParams(GetOwner())
|
||||||
|
#define IGNORE_THIS_PARAMS GetIgnoreActorParams(this)
|
||||||
|
|
||||||
|
inline FCollisionQueryParams GetIgnoreActorParams(const AActor* Actor) {
|
||||||
|
FCollisionQueryParams Params;
|
||||||
|
Params.AddIgnoredActor(Actor);
|
||||||
|
return Params;
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user