void URealmCharacterMovementComponent::IgnoreMovement() { //end any dashes this character may be performing EndDash(); StopMovementImmediately(); SetMovementMode(MOVE_None); }
void URealmCharacterMovementComponent::EndDash() { if (!bCharacterDashing) return; bCharacterDashing = false; StopMovementImmediately(); SetMovementMode(MOVE_Walking); AGameCharacter* gc = Cast<AGameCharacter>(CharacterOwner); if (IsValid(gc)) { gc->bAcceptingMoveCommands = true; gc->CharacterDashFinished(); } }
bool URealmCharacterMovementComponent::HandlePendingLaunch() { if (!PendingLaunchVelocity.IsZero() && HasValidData()) { Velocity = PendingLaunchVelocity; PendingLaunchVelocity = FVector::ZeroVector; if (bCharacterWantsDash) { StopMovementImmediately(); SetMovementMode(MOVE_Flying); bCharacterWantsDash = false; bCharacterDashing = true; } else SetMovementMode(MOVE_Falling); return true; } return false; }
// Called every frame void UCustomMovementComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) { Super::TickComponent(DeltaTime, TickType, ThisTickFunction); // Stop if CapsuleComponet is invalid if (CapsuleComponent == NULL) { return; } // Update CurrentTraceShapeScale if (CurrentTraceShapeScale != TraceShapeScale) { CurrentTraceShapeScale = FMath::Clamp<float>(TraceShapeScale, 0.0f, 1.0f - KINDA_SMALL_NUMBER); } /* Local Variables */ const EDrawDebugTrace::Type DrawDebugType = bDebugIsEnabled ? DebugDrawType : EDrawDebugTrace::None; const ECollisionChannel CollisionChannel = CapsuleComponent->GetCollisionObjectType(); const FVector TraceStart = CapsuleComponent->GetComponentLocation(); const float CapsuleHalfHeight = CapsuleComponent->GetScaledCapsuleHalfHeight(); float ShapeRadius = CapsuleComponent->GetScaledCapsuleRadius() * 0.99f; FVector TraceEnd = TraceStart - CapsuleComponent->GetUpVector()* (CapsuleHalfHeight - ShapeRadius + GroundHitToleranceDistance + 1.0f); FHitResult HitResult; TArray<AActor*> ActorsToIgnore; #pragma region Standing/Falling Definition /** Testing if the Capsule is in air or standing on a walkable surface*/ UKismetSystemLibrary::SphereTraceSingle_NEW(this, TraceStart, TraceEnd, ShapeRadius, UEngineTypes::ConvertToTraceType(TraceChannel), true, ActorsToIgnore, DrawDebugType, HitResult, true); bIsInAir = !HitResult.bBlockingHit; TimeInAir = bIsInAir ? TimeInAir + DeltaTime : 0.0f; CurrentStandingSurface = HitResult; #pragma endregion #pragma region Update Capsule linearDamping /** * Update Capsule linearDamping * If Grounded L-D is set to 1.0f , in same cases helps to stop the capsule when we are not moving * If falling case , stetting L-D to 0.01f , Helps to reach the wanted jump height when JumpImpulse is applied */ if (CapsuleComponent->GetLinearDamping() != 0.01f && bIsInAir) { CapsuleComponent->SetLinearDamping(0.01f); } else if (CapsuleComponent->GetLinearDamping() != 1.0f && !bIsInAir) { CapsuleComponent->SetLinearDamping(1.0f); } else if (TimeInAir > 1.0f && PlanetActor != nullptr && !bIsJumping) { CapsuleComponent->SetLinearDamping(0.5f); } #pragma endregion #pragma region Gravity Settings /* Gravity Settings : Update Current Gravity info*/ if (bResetVelocityOnGravitySwitch) { if (bIsInAir && bCanResetGravity && TimeInAir >= GravitySwitchDelay) { StopMovementImmediately(); bCanResetGravity = false; } else if (!bIsInAir && !bCanResetGravity) { bCanResetGravity = true; } } if (!bIsInAir && StandingVerticalOrientation == EVerticalOrientation::EVO_SurfaceNormal) { if (bUseCapsuleHit) { if (CapsuleHitResult.IsValidBlockingHit()) { CurrentTracedSurface = CapsuleHitResult; } } else { ShapeRadius = CapsuleComponent->GetScaledCapsuleRadius() * CurrentTraceShapeScale; TraceEnd = TraceStart - CapsuleComponent->GetUpVector()* (CapsuleHalfHeight + GroundHitToleranceDistance + 1.0f); if (TraceShape == ETraceShape::ETS_Line) { UKismetSystemLibrary::LineTraceSingle_NEW(this, TraceStart, TraceEnd, UEngineTypes::ConvertToTraceType(TraceChannel), true, ActorsToIgnore, DrawDebugType, HitResult, true); } else if (TraceShape == ETraceShape::ETS_Sphere) { TraceEnd += CapsuleComponent->GetUpVector() * ShapeRadius; UKismetSystemLibrary::SphereTraceSingle_NEW(this, TraceStart, TraceEnd, ShapeRadius, UEngineTypes::ConvertToTraceType(TraceChannel), true, ActorsToIgnore, DrawDebugType, HitResult, true); } else { TraceEnd += CapsuleComponent->GetUpVector() * ShapeRadius; UKismetSystemLibrary::BoxTraceSingle(this, TraceStart, TraceEnd, FVector(1, 1, 1)*ShapeRadius, CapsuleComponent->GetComponentRotation(), UEngineTypes::ConvertToTraceType(TraceChannel), true, ActorsToIgnore, DrawDebugType, HitResult, true); } CurrentTracedSurface = HitResult; } const bool bOnWalkableSurface = CurrentTracedSurface.IsValidBlockingHit(); if (bOnWalkableSurface) { SurfaceBasedGravityInfo.GravityDirection = -HitResult.ImpactNormal; CurrentGravityInfo = SurfaceBasedGravityInfo; CurrentOrientationInfo = OrientationSettings.SurfaceBasedGravity; } } else if ((!bIsInAir && StandingVerticalOrientation == EVerticalOrientation::EVO_GravityDirection) || (bIsInAir && FallingVerticalOrientation == EVerticalOrientation::EVO_GravityDirection)) { if (!bIsInAir || TimeInAir > GravitySwitchDelay) { switch (CustomGravityType) { case EGravityType::EGT_Default: { if (CapsuleComponent->IsGravityEnabled() && GravityScale == 0) { CapsuleComponent->SetEnableGravity(false); CapsuleComponent->SetAllPhysicsLinearVelocity(FVector::ZeroVector); } else if (!CapsuleComponent->IsGravityEnabled() && GravityScale != 0) { CapsuleComponent->SetEnableGravity(true); } CurrentGravityInfo = FGravityInfo(-CapsuleComponent->GetWorld()->GetGravityZ(), -FVector::UpVector, EForceMode::EFM_Acceleration, true); CurrentOrientationInfo = OrientationSettings.DefaultGravity; UpdateCapsuleRotation(DeltaTime, -CurrentGravityInfo.GravityDirection, CurrentOrientationInfo.bIsInstant, CurrentOrientationInfo.RotationInterpSpeed); return; } case EGravityType::EGT_Custom: { CurrentGravityInfo = CustomGravityInfo; CurrentOrientationInfo = OrientationSettings.CustomGravity; break; } case EGravityType::EGT_GlobalCustom: { CurrentGravityInfo = UCustomGravityManager::GetGlobalCustomGravityInfo(); CurrentOrientationInfo = OrientationSettings.GlobalCustomGravity; break; } case EGravityType::EGT_Point: { if (PlanetActor == NULL) { return; } CurrentGravityInfo = PlanetActor->GetGravityinfo(CapsuleComponent->GetComponentLocation()); CurrentOrientationInfo = OrientationSettings.PointGravity; break; } } } } #pragma endregion /** Variables definition & initialization */ const FVector CurrentGravityDirection = CurrentGravityInfo.GravityDirection; const bool bUseAccelerationChange = (CurrentGravityInfo.ForceMode == EForceMode::EFM_Acceleration); const bool bShouldUseStepping = CurrentGravityInfo.bForceSubStepping; const float CurrentGravityPower = CurrentGravityInfo.GravityPower * GravityScale; const FVector GravityForce = CurrentGravityDirection.GetSafeNormal() * CurrentGravityPower; const float InterpSpeed = CurrentOrientationInfo.RotationInterpSpeed; const bool bOrientationIsInstant = CurrentOrientationInfo.bIsInstant; /* Update Rotation : Orient Capsule's up vector to have the same direction as -gravityDirection */ UpdateCapsuleRotation(DeltaTime, -CurrentGravityDirection, bOrientationIsInstant, InterpSpeed); /* Apply Gravity*/ ApplyGravity(GravityForce, bShouldUseStepping, bUseAccelerationChange); }