Refactor CMC and fix camera combat path reference

This commit is contained in:
Maxime Maurin 2023-11-24 21:58:52 +01:00
parent aedd5ee35e
commit f4f39995a5
9 changed files with 60 additions and 42 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -86,32 +86,12 @@ void UPwnCharacterMovementComponent::EnterSplineFollowMode() {
IsFollowingSpline = true;
SetMovementMode(MOVE_Custom, SplineWalking);
const UPwnGameplayModeSubsystem* Subsystem = GetWorld()->GetSubsystem<UPwnGameplayModeSubsystem>();
check(Subsystem);
APwnCombatPlatformerPath* OutCombatPath;
if (Subsystem->FindClosestCombatPathLocation(UpdatedComponent->GetComponentLocation(), OutCombatPath)) {
CombatPath = OutCombatPath;
DotDirection = CombatPath->Reversed ? -1.0f : 1.0f;
const float ClosestInputKey = CombatPath->Spline->FindInputKeyClosestToWorldLocation(UpdatedComponent->GetComponentLocation());
FVector ClosestLocation = CombatPath->Spline->GetLocationAtSplineInputKey(ClosestInputKey, ESplineCoordinateSpace::World);
FHitResult Hit;
if (GetWorld()->LineTraceSingleByChannel(Hit, ClosestLocation, ClosestLocation + FVector(0.0f, 0.0f, -LineTraceDistance),
ECC_Visibility, IGNORE_OWNER_PARAMS)) {
const float SplineKey = CombatPath->FlattenedSpline->FindInputKeyClosestToWorldLocation(Hit.ImpactPoint);
DistanceAlongSpline = CombatPath->FlattenedSpline->GetDistanceAlongSplineAtSplineInputKey(SplineKey);
ClosestLocation.Z += CharacterOwner->GetCapsuleComponent()->GetScaledCapsuleHalfHeight();
UpdatedComponent->SetWorldLocation(ClosestLocation);
}
}
UpdateCurrentCombatPath(true);
}
void UPwnCharacterMovementComponent::ExitSplineFollowMode() {
IsFollowingSpline = false;
CombatPath = nullptr;
SetMovementMode(MOVE_Walking);
}
@ -119,6 +99,36 @@ bool UPwnCharacterMovementComponent::IsCustomMovementMode(const ECustomMovementM
return MovementMode == MOVE_Custom && CustomMovementMode == Mode;
}
bool UPwnCharacterMovementComponent::LineTraceToGround(FHitResult& OutHit, const FVector& StartLocation) const {
const FVector EndLocation = StartLocation + FVector(0.0f, 0.0f, -LineTraceDistance);
return GetWorld()->LineTraceSingleByChannel(OutHit, StartLocation, EndLocation, ECC_Visibility, IGNORE_OWNER_PARAMS);
}
void UPwnCharacterMovementComponent::UpdateCurrentCombatPath(const bool UpdateLocation) {
APwnCombatPlatformerPath* OutCombatPath;
FHitResult Hit;
if (LineTraceToGround(Hit, UpdatedComponent->GetComponentLocation())
&& UPwnGameplayModeSubsystem::Get(this).FindClosestCombatPathLocation(Hit.ImpactPoint, OutCombatPath)
&& OutCombatPath != CombatPath) {
CombatPath = OutCombatPath;
DotDirection = CombatPath->Reversed ? -1.0f : 1.0f;
const float ClosestInputKey = CombatPath->Spline->FindInputKeyClosestToWorldLocation(UpdatedComponent->GetComponentLocation());
const FVector ClosestLocation = CombatPath->Spline->GetLocationAtSplineInputKey(ClosestInputKey, ESplineCoordinateSpace::World);
if (LineTraceToGround(Hit, ClosestLocation)) {
const float SplineKey = CombatPath->FlattenedSpline->FindInputKeyClosestToWorldLocation(Hit.ImpactPoint);
DistanceAlongSpline = CombatPath->FlattenedSpline->GetDistanceAlongSplineAtSplineInputKey(SplineKey);
if (UpdateLocation) {
FVector NewLocation = Hit.ImpactPoint;
NewLocation.Z += CharacterOwner->GetCapsuleComponent()->GetScaledCapsuleHalfHeight();
UpdatedComponent->SetWorldLocation(NewLocation);
}
}
}
}
void UPwnCharacterMovementComponent::UpdateTangentAndAcceleration() {
Tangent2D = CombatPath->FlattenedSpline->GetTangentAtDistanceAlongSpline(DistanceAlongSpline, ESplineCoordinateSpace::World).GetSafeNormal2D();
// Recalculate acceleration so the input is relative to the spline
@ -150,9 +160,7 @@ void UPwnCharacterMovementComponent::UpdatePawnVelocity(const float TimeTick) {
void UPwnCharacterMovementComponent::UpdateDistanceAlongSpline() {
FHitResult Hit;
if (GetWorld()->LineTraceSingleByChannel(Hit, UpdatedComponent->GetComponentLocation(),
UpdatedComponent->GetComponentLocation() + FVector(0.0f, 0.0f, -LineTraceDistance),
ECC_Visibility, IGNORE_OWNER_PARAMS)) {
if (LineTraceToGround(Hit, UpdatedComponent->GetComponentLocation())) {
const FVector ImpactPoint = Hit.ImpactPoint;
const float InputKey = CombatPath->FlattenedSpline->FindInputKeyClosestToWorldLocation(ImpactPoint);
DistanceAlongSpline = CombatPath->FlattenedSpline->GetDistanceAlongSplineAtSplineInputKey(InputKey);
@ -171,6 +179,8 @@ void UPwnCharacterMovementComponent::PhysSplineWalking(const float DeltaTime, in
return;
}
UpdateCurrentCombatPath(); /* -- PAWN MODIFICATIONS -- */
if (!CharacterOwner || (!CharacterOwner->Controller && !bRunPhysicsWithNoController && !HasAnimRootMotion() && !CurrentRootMotion.
HasOverrideVelocity() && (CharacterOwner->GetLocalRole() != ROLE_SimulatedProxy))) {
Acceleration = FVector::ZeroVector;
@ -368,13 +378,12 @@ void UPwnCharacterMovementComponent::PhysSplineWalking(const float DeltaTime, in
UpdateLocationOnFlattenedSpline();
}
UE_DISABLE_OPTIMIZATION
void UPwnCharacterMovementComponent::PhysSplineFalling(const float DeltaTime, int32 Iterations) {
if (DeltaTime < MIN_TICK_TIME) {
return;
}
UpdateCurrentCombatPath(); /* -- PAWN MODIFICATIONS -- */
UpdateTangentAndAcceleration(); /* -- PAWN MODIFICATIONS -- */
FVector FallAcceleration = GetFallingLateralAcceleration(DeltaTime);
@ -579,8 +588,6 @@ void UPwnCharacterMovementComponent::PhysSplineFalling(const float DeltaTime, in
: NewVelocity;
}
//UpdatePawnVelocity(TimeTick); /* -- PAWN MODIFICATIONS -- */
if (SubTimeTickRemaining > UE_KINDA_SMALL_NUMBER && (Delta | Adjusted) > 0.f) {
// Move in deflected direction.
SafeMoveUpdatedComponent(Delta, PawnRotation, true, Hit);
@ -631,7 +638,6 @@ void UPwnCharacterMovementComponent::PhysSplineFalling(const float DeltaTime, in
Velocity = HasAnimRootMotion() || CurrentRootMotion.HasOverrideVelocityWithIgnoreZAccumulate()
? FVector(Velocity.X, Velocity.Y, NewVelocity.Z)
: NewVelocity;
//UpdatePawnVelocity(TimeTick); /* -- PAWN MODIFICATIONS -- */
}
// bDitch=true means that pawn is straddling two slopes, neither of which it can stand on
@ -661,8 +667,6 @@ void UPwnCharacterMovementComponent::PhysSplineFalling(const float DeltaTime, in
Velocity.Y += 0.25f * GetMaxSpeed() * (RandomStream.FRand() - 0.5f);
Velocity.Z = FMath::Max<float>(JumpZVelocity * 0.25f, 1.f);
//UpdatePawnVelocity(TimeTick); /* -- PAWN MODIFICATIONS -- */
Delta = Velocity * TimeTick;
SafeMoveUpdatedComponent(Delta, PawnRotation, true, Hit);
@ -683,5 +687,3 @@ void UPwnCharacterMovementComponent::PhysSplineFalling(const float DeltaTime, in
UpdateDistanceAlongSpline();
UpdateLocationOnFlattenedSpline();
}
UE_ENABLE_OPTIMIZATION

View File

@ -3,6 +3,13 @@
#include "Components/SplineComponent.h"
#include "GameplayModes/Combat/PwnCombatPlatformerPath.h"
UPwnGameplayModeSubsystem& UPwnGameplayModeSubsystem::Get(const UObject* WorldContextObject) {
const UWorld* World = GEngine->GetWorldFromContextObjectChecked(WorldContextObject);
UPwnGameplayModeSubsystem* GameplayModeSubsystem = World->GetSubsystem<UPwnGameplayModeSubsystem>();
check(GameplayModeSubsystem);
return *GameplayModeSubsystem;
}
void UPwnGameplayModeSubsystem::Initialize(FSubsystemCollectionBase& Collection) {
Super::Initialize(Collection);
CurrentGameplayMode = EPwnGameplayMode::Narrative;

View File

@ -51,6 +51,10 @@ public:
bool IsCustomMovementMode(const ECustomMovementMode Mode) const;
private:
bool LineTraceToGround(FHitResult& OutHit, const FVector& StartLocation) const;
void UpdateCurrentCombatPath(const bool UpdateLocation = false);
/**
* Updates the tangent in function of the current distance along the spline. Then updates the acceleration so it will simulate an input in the
* direction of the tangent.

View File

@ -19,6 +19,8 @@ class PAWN_API UPwnGameplayModeSubsystem : public UWorldSubsystem {
GENERATED_BODY()
public:
static UPwnGameplayModeSubsystem& Get(const UObject* WorldContextObject);
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
virtual void Deinitialize() override;