climbing mode polished

This commit is contained in:
2026-04-29 09:01:04 +02:00
parent 563df1ffc8
commit 74882e634b
3 changed files with 79 additions and 64 deletions

View File

@@ -20,68 +20,7 @@ void UCustomCharacterMovementComponent::PhysCustom(float DeltaTime, int32 Iterat
{
case 0:
{
if (DeltaTime < MIN_TICK_TIME)
{
return;
}
RestorePreAdditiveRootMotionVelocity();
if (!HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity())
{
if (bCheatFlying && Acceleration.IsZero())
{
Velocity = FVector::ZeroVector;
}
//const float Friction = 0.5f * GetPhysicsVolume()->FluidFriction;
constexpr float Friction = 5.f;
CalcVelocity(DeltaTime, Friction, true, GetMaxBrakingDeceleration());
}
ApplyRootMotionToVelocity(DeltaTime);
bJustTeleported = false;
FVector OldLocation = UpdatedComponent->GetComponentLocation();
const FVector Adjusted = Velocity * DeltaTime;
FHitResult Hit(1.f);
SafeMoveUpdatedComponent(Adjusted, UpdatedComponent->GetComponentQuat(), true, Hit);
if (Hit.Time < 1.f)
{
SlideAlongSurface(Velocity * DeltaTime, 1.f - Hit.Time, Hit.Normal, Hit, true);
}
const ACharacter* Character = Cast<ACharacter>(GetOwner());
FHitResult WallHit;
const bool bWallFound = SweepForwardForWall(Character, WallHit);
if (bWallFound)
{
const FVector SurfaceNormal = WallHit.Normal;
// Update Location
const FVector TargetLocation = WallHit.Location + (SurfaceNormal * 0.1f);
const FVector NewLocation = FMath::VInterpTo(UpdatedComponent->GetComponentLocation(), TargetLocation, DeltaTime, 2.f);
UpdatedComponent->SetWorldLocation(NewLocation);
// Update Rotation
const FRotator TargetRotation = FRotationMatrix::MakeFromXZ(-SurfaceNormal, FVector::UpVector).Rotator();
const FRotator NewRotation = FMath::RInterpTo(UpdatedComponent->GetComponentRotation(), TargetRotation, DeltaTime, 2.f);
UpdatedComponent->SetWorldRotation(NewRotation);
}
else
{
// Reset Rotation and set MovementMode to Falling
const FRotator NewRotation = FRotator(0.0f, UpdatedComponent->GetComponentRotation().Yaw, 0.0f);
UpdatedComponent->SetWorldRotation(NewRotation);
SetMovementMode(MOVE_Falling);
}
if (!bJustTeleported && !HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity())
{
Velocity = (UpdatedComponent->GetComponentLocation() - OldLocation) / DeltaTime;
}
PhysClimbing(DeltaTime, Iterations);
break;
}
@@ -93,6 +32,81 @@ void UCustomCharacterMovementComponent::PhysCustom(float DeltaTime, int32 Iterat
}
}
void UCustomCharacterMovementComponent::PhysClimbing(float DeltaTime, int32 Iterations)
{
if (DeltaTime < MIN_TICK_TIME)
{
return;
}
RestorePreAdditiveRootMotionVelocity();
if (!HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity())
{
if (bCheatFlying && Acceleration.IsZero())
{
Velocity = FVector::ZeroVector;
}
//const float Friction = 0.5f * GetPhysicsVolume()->FluidFriction;
constexpr float Friction = 5.f;
CalcVelocity(DeltaTime, Friction, true, GetMaxBrakingDeceleration());
}
ApplyRootMotionToVelocity(DeltaTime);
bJustTeleported = false;
FVector OldLocation = UpdatedComponent->GetComponentLocation();
const FVector Adjusted = Velocity * DeltaTime;
FHitResult Hit(1.f);
SafeMoveUpdatedComponent(Adjusted, UpdatedComponent->GetComponentQuat(), true, Hit);
if (Hit.Time < 1.f)
{
SlideAlongSurface(Velocity * DeltaTime, 1.f - Hit.Time, Hit.Normal, Hit, true);
}
const ACharacter* Character = Cast<ACharacter>(GetOwner());
FHitResult WallHit;
const bool bWallFound = SweepForwardForWall(Character, WallHit);
if (bWallFound)
{
const FVector SurfaceNormal = WallHit.Normal;
// Update Location
const FVector TargetLocation = WallHit.Location + (SurfaceNormal * 0.1f);
const FVector NewLocation = FMath::VInterpTo(UpdatedComponent->GetComponentLocation(), TargetLocation, DeltaTime, 2.f);
UpdatedComponent->SetWorldLocation(NewLocation);
// Update Rotation
FRotator TargetRotation = FRotationMatrix::MakeFromXZ(-SurfaceNormal, FVector::UpVector).Rotator();
if (TargetRotation.Pitch < -70.0f)
{
TargetRotation = FRotator(0.0f, UpdatedComponent->GetComponentRotation().Yaw, 0.0f);
UpdatedComponent->SetWorldRotation(TargetRotation);
SetMovementMode(MOVE_Falling);
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Blue, TEXT("Standing up"));
}
else
{
const FRotator NewRotation = FMath::RInterpTo(UpdatedComponent->GetComponentRotation(), TargetRotation, DeltaTime, 2.f);
UpdatedComponent->SetWorldRotation(NewRotation);
}
}
else
{
// Reset Rotation and set MovementMode to Falling
const FRotator NewRotation = FRotator(0.0f, UpdatedComponent->GetComponentRotation().Yaw, 0.0f);
UpdatedComponent->SetWorldRotation(NewRotation);
SetMovementMode(MOVE_Falling);
}
if (!bJustTeleported && !HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity())
{
Velocity = (UpdatedComponent->GetComponentLocation() - OldLocation) / DeltaTime;
}
}
void UCustomCharacterMovementComponent::OnMovementModeChanged(EMovementMode PreviousMovementMode, uint8 PreviousCustomMode)
{
Super::OnMovementModeChanged(PreviousMovementMode, PreviousCustomMode);