// // Copyright 2025 https://yuewu.dev/en All Rights Reserved. // // // #include "Movement/GMS_CharacterMovementComponent.h" // // #include "GMS_CharacterMovementSystemComponent.h" // #include "GMS_MovementSystemComponent.h" // #include "GameFramework/Character.h" // #include "Locomotions/GMS_MainAnimInstance.h" // #include "Settings/GMS_SettingObjectLibrary.h" // #include "Utility/GMS_Constants.h" // #include "Utility/GMS_Log.h" // #include "Utility/GMS_Math.h" // // #include UE_INLINE_GENERATED_CPP_BY_NAME(GMS_CharacterMovementComponent) // // UGMS_CharacterMovementComponent::UGMS_CharacterMovementComponent(const FObjectInitializer& ObjectInitializer): Super(ObjectInitializer) // { // } // // void UGMS_CharacterMovementComponent::InitializeComponent() // { // Super::InitializeComponent(); // if (CharacterOwner) // { // UGMS_CharacterMovementSystemComponent* NewMovementSystem = CharacterOwner->FindComponentByClass(); // if (NewMovementSystem == nullptr) // { // GMS_CLOG(Warning, "Requires GMS Character Movement System Component to function!") // return; // } // MovementSystem = NewMovementSystem; // } // } // // void UGMS_CharacterMovementComponent::SetUpdatedComponent(USceneComponent* NewUpdatedComponent) // { // Super::SetUpdatedComponent(NewUpdatedComponent); // if (CharacterOwner) // { // UGMS_CharacterMovementSystemComponent* NewMovementSystem = CharacterOwner->FindComponentByClass(); // if (NewMovementSystem == nullptr) // { // GMS_CLOG(Warning, "Requires GMS Character Movement System Component to function!") // return; // } // MovementSystem = NewMovementSystem; // } // } // // bool UGMS_CharacterMovementComponent::HasValidData() const // { // return Super::HasValidData() && IsValid(MovementSystem); // } // // void UGMS_CharacterMovementComponent::TickCharacterPose(float DeltaTime) // { // Super::TickCharacterPose(DeltaTime); // } // // void UGMS_CharacterMovementComponent::PhysicsRotation(float DeltaTime) // { // if (bUseNativeRotation) // { // Super::PhysicsRotation(DeltaTime); // } // else // { // GMS_PhysicsRotation(DeltaTime); // } // } // // void UGMS_CharacterMovementComponent::GMS_TurnToDesiredRotation(const FRotator& CurrentRotation, FRotator DesiredRotation, FRotator DeltaRot) // { // const bool bWantsToBeVertical = ShouldRemainVertical(); // // if (bWantsToBeVertical) // { // if (HasCustomGravity()) // { // FRotator GravityRelativeDesiredRotation = (GetWorldToGravityTransform() * DesiredRotation.Quaternion()).Rotator(); // GravityRelativeDesiredRotation.Pitch = 0.f; // GravityRelativeDesiredRotation.Yaw = FRotator::NormalizeAxis(GravityRelativeDesiredRotation.Yaw); // GravityRelativeDesiredRotation.Roll = 0.f; // DesiredRotation = (GetWorldToGravityTransform() * GravityRelativeDesiredRotation.Quaternion()).Rotator(); // } // else // { // DesiredRotation.Pitch = 0.f; // DesiredRotation.Yaw = FRotator::NormalizeAxis(DesiredRotation.Yaw); // DesiredRotation.Roll = 0.f; // } // } // else // { // DesiredRotation.Normalize(); // } // // // Accumulate a desired new rotation. // constexpr float AngleTolerance = 1e-3f; // // if (!CurrentRotation.Equals(DesiredRotation, AngleTolerance)) // { // // If we'd be prevented from becoming vertical, override the non-yaw rotation rates to allow the character to snap upright // // static bool PreventNonVerticalOrientationBlock = true; // if (PreventNonVerticalOrientationBlock && bWantsToBeVertical) // { // if (FMath::IsNearlyZero(DeltaRot.Pitch)) // { // DeltaRot.Pitch = 360.0; // } // if (FMath::IsNearlyZero(DeltaRot.Roll)) // { // DeltaRot.Roll = 360.0; // } // } // // if (HasCustomGravity()) // { // FRotator GravityRelativeCurrentRotation = (GetWorldToGravityTransform() * CurrentRotation.Quaternion()).Rotator(); // FRotator GravityRelativeDesiredRotation = (GetWorldToGravityTransform() * DesiredRotation.Quaternion()).Rotator(); // // // PITCH // if (!FMath::IsNearlyEqual(GravityRelativeCurrentRotation.Pitch, GravityRelativeDesiredRotation.Pitch, AngleTolerance)) // { // // GravityRelativeDesiredRotation.Pitch = UGMS_Math::ExponentialDecayAngle(GravityRelativeCurrentRotation.Pitch, // // GravityRelativeDesiredRotation.Pitch, DeltaTime, DeltaRot.Pitch); // GravityRelativeDesiredRotation.Pitch = FMath::FixedTurn(GravityRelativeCurrentRotation.Pitch, GravityRelativeDesiredRotation.Pitch, DeltaRot.Pitch); // } // // // YAW // if (!FMath::IsNearlyEqual(GravityRelativeCurrentRotation.Yaw, GravityRelativeDesiredRotation.Yaw, AngleTolerance)) // { // // GravityRelativeDesiredRotation.Yaw = UGMS_Math::ExponentialDecayAngle(GravityRelativeCurrentRotation.Yaw, // // GravityRelativeDesiredRotation.Yaw, DeltaTime, DeltaRot.Yaw); // GravityRelativeDesiredRotation.Yaw = FMath::FixedTurn(GravityRelativeCurrentRotation.Yaw, GravityRelativeDesiredRotation.Yaw, DeltaRot.Yaw); // } // // // ROLL // if (!FMath::IsNearlyEqual(GravityRelativeCurrentRotation.Roll, GravityRelativeDesiredRotation.Roll, AngleTolerance)) // { // // GravityRelativeDesiredRotation.Roll = UGMS_Math::ExponentialDecayAngle(GravityRelativeCurrentRotation.Roll, // // GravityRelativeDesiredRotation.Roll, DeltaTime, DeltaRot.Roll); // GravityRelativeDesiredRotation.Roll = FMath::FixedTurn(GravityRelativeCurrentRotation.Roll, GravityRelativeDesiredRotation.Roll, DeltaRot.Roll); // } // // DesiredRotation = (GetWorldToGravityTransform() * GravityRelativeDesiredRotation.Quaternion()).Rotator(); // } // else // { // // PITCH // if (!FMath::IsNearlyEqual(CurrentRotation.Pitch, DesiredRotation.Pitch, AngleTolerance)) // { // // DesiredRotation.Pitch = UGMS_Math::ExponentialDecayAngle(CurrentRotation.Pitch, DesiredRotation.Pitch, DeltaTime, DeltaRot.Pitch); // DesiredRotation.Pitch = FMath::FixedTurn(CurrentRotation.Pitch, DesiredRotation.Pitch, DeltaRot.Pitch); // } // // // YAW // if (!FMath::IsNearlyEqual(CurrentRotation.Yaw, DesiredRotation.Yaw, AngleTolerance)) // { // // DesiredRotation.Yaw = UGMS_Math::ExponentialDecayAngle(CurrentRotation.Yaw, DesiredRotation.Yaw, DeltaTime, DeltaRot.Yaw); // DesiredRotation.Yaw = FMath::FixedTurn(CurrentRotation.Yaw, DesiredRotation.Yaw, DeltaRot.Yaw); // } // // // ROLL // if (!FMath::IsNearlyEqual(CurrentRotation.Roll, DesiredRotation.Roll, AngleTolerance)) // { // // DesiredRotation.Roll = UGMS_Math::ExponentialDecayAngle(CurrentRotation.Roll, DesiredRotation.Roll, DeltaTime, DeltaRot.Yaw); // DesiredRotation.Roll = FMath::FixedTurn(CurrentRotation.Roll, DesiredRotation.Roll, DeltaRot.Roll); // } // } // // // Set the new rotation. // DesiredRotation.DiagnosticCheckNaN(TEXT("CharacterMovementComponent::PhysicsRotation(): DesiredRotation")); // MoveUpdatedComponent(FVector::ZeroVector, DesiredRotation, /*bSweep*/ false); // } // } // // void UGMS_CharacterMovementComponent::GMS_TurnToDesiredRotationWithRotationRate(const FRotator& CurrentRotation, FRotator DesiredRotation, FRotator DeltaRot) // { // const bool bWantsToBeVertical = ShouldRemainVertical(); // // if (bWantsToBeVertical) // { // if (HasCustomGravity()) // { // FRotator GravityRelativeDesiredRotation = (GetWorldToGravityTransform() * DesiredRotation.Quaternion()).Rotator(); // GravityRelativeDesiredRotation.Pitch = 0.f; // GravityRelativeDesiredRotation.Yaw = FRotator::NormalizeAxis(GravityRelativeDesiredRotation.Yaw); // GravityRelativeDesiredRotation.Roll = 0.f; // DesiredRotation = (GetWorldToGravityTransform() * GravityRelativeDesiredRotation.Quaternion()).Rotator(); // } // else // { // DesiredRotation.Pitch = 0.f; // DesiredRotation.Yaw = FRotator::NormalizeAxis(DesiredRotation.Yaw); // DesiredRotation.Roll = 0.f; // } // } // else // { // DesiredRotation.Normalize(); // } // // // Accumulate a desired new rotation. // constexpr float AngleTolerance = 1e-3f; // // if (!CurrentRotation.Equals(DesiredRotation, AngleTolerance)) // { // // If we'd be prevented from becoming vertical, override the non-yaw rotation rates to allow the character to snap upright // // static bool PreventNonVerticalOrientationBlock = true; // if (PreventNonVerticalOrientationBlock && bWantsToBeVertical) // { // if (FMath::IsNearlyZero(DeltaRot.Pitch)) // { // DeltaRot.Pitch = 360.0; // } // if (FMath::IsNearlyZero(DeltaRot.Roll)) // { // DeltaRot.Roll = 360.0; // } // } // // if (HasCustomGravity()) // { // FRotator GravityRelativeCurrentRotation = (GetWorldToGravityTransform() * CurrentRotation.Quaternion()).Rotator(); // FRotator GravityRelativeDesiredRotation = (GetWorldToGravityTransform() * DesiredRotation.Quaternion()).Rotator(); // // // PITCH // if (!FMath::IsNearlyEqual(GravityRelativeCurrentRotation.Pitch, GravityRelativeDesiredRotation.Pitch, AngleTolerance)) // { // GravityRelativeDesiredRotation.Pitch = FMath::FixedTurn(GravityRelativeCurrentRotation.Pitch, GravityRelativeDesiredRotation.Pitch, DeltaRot.Pitch); // } // // // YAW // if (!FMath::IsNearlyEqual(GravityRelativeCurrentRotation.Yaw, GravityRelativeDesiredRotation.Yaw, AngleTolerance)) // { // GravityRelativeDesiredRotation.Yaw = FMath::FixedTurn(GravityRelativeCurrentRotation.Yaw, GravityRelativeDesiredRotation.Yaw, DeltaRot.Yaw); // } // // // ROLL // if (!FMath::IsNearlyEqual(GravityRelativeCurrentRotation.Roll, GravityRelativeDesiredRotation.Roll, AngleTolerance)) // { // GravityRelativeDesiredRotation.Roll = FMath::FixedTurn(GravityRelativeCurrentRotation.Roll, GravityRelativeDesiredRotation.Roll, DeltaRot.Roll); // } // // DesiredRotation = (GetWorldToGravityTransform() * GravityRelativeDesiredRotation.Quaternion()).Rotator(); // } // else // { // // PITCH // if (!FMath::IsNearlyEqual(CurrentRotation.Pitch, DesiredRotation.Pitch, AngleTolerance)) // { // DesiredRotation.Pitch = FMath::FixedTurn(CurrentRotation.Pitch, DesiredRotation.Pitch, DeltaRot.Pitch); // } // // // YAW // if (!FMath::IsNearlyEqual(CurrentRotation.Yaw, DesiredRotation.Yaw, AngleTolerance)) // { // DesiredRotation.Yaw = FMath::FixedTurn(CurrentRotation.Yaw, DesiredRotation.Yaw, DeltaRot.Yaw); // } // // // ROLL // if (!FMath::IsNearlyEqual(CurrentRotation.Roll, DesiredRotation.Roll, AngleTolerance)) // { // DesiredRotation.Roll = FMath::FixedTurn(CurrentRotation.Roll, DesiredRotation.Roll, DeltaRot.Roll); // } // } // // // Set the new rotation. // DesiredRotation.DiagnosticCheckNaN(TEXT("CharacterMovementComponent::PhysicsRotation(): DesiredRotation")); // MoveUpdatedComponent(FVector::ZeroVector, DesiredRotation, /*bSweep*/ false); // } // } // // void UGMS_CharacterMovementComponent::GMS_PhysicsRotation_Implementation(float DeltaTime) // { // if (!(bOrientRotationToMovement || bUseControllerDesiredRotation)) // { // return; // } // // if (!HasValidData() || (!CharacterOwner->Controller && !bRunPhysicsWithNoController)) // { // return; // } // // FRotator CurrentRotation = UpdatedComponent->GetComponentRotation(); // Normalized // CurrentRotation.DiagnosticCheckNaN(TEXT("CharacterMovementComponent::PhysicsRotation(): CurrentRotation")); // // FRotator DeltaRot = GetDeltaRotation(DeltaTime); // DeltaRot.DiagnosticCheckNaN(TEXT("CharacterMovementComponent::PhysicsRotation(): GetDeltaRotation")); // // FRotator DesiredRotation = CurrentRotation; // if (bOrientRotationToMovement) // { // DesiredRotation = GMS_ComputeOrientToDesiredMovementRotation(CurrentRotation, DeltaTime, DeltaRot); // } // else if (CharacterOwner->Controller && bUseControllerDesiredRotation) // { // DesiredRotation = CharacterOwner->Controller->GetDesiredRotation(); // // DesiredRotation = MovementSystem->GetViewState().Rotation; // } // else if (!CharacterOwner->Controller && bRunPhysicsWithNoController && bUseControllerDesiredRotation) // { // if (AController* ControllerOwner = Cast(CharacterOwner->GetOwner())) // { // DesiredRotation = ControllerOwner->GetDesiredRotation(); // } // } // else // { // return; // } // // const bool bWantsToBeVertical = ShouldRemainVertical(); // // if (bWantsToBeVertical) // { // if (HasCustomGravity()) // { // FRotator GravityRelativeDesiredRotation = (GetGravityToWorldTransform() * DesiredRotation.Quaternion()).Rotator(); // GravityRelativeDesiredRotation.Pitch = 0.f; // GravityRelativeDesiredRotation.Yaw = FRotator::NormalizeAxis(GravityRelativeDesiredRotation.Yaw); // GravityRelativeDesiredRotation.Roll = 0.f; // DesiredRotation = (GetWorldToGravityTransform() * GravityRelativeDesiredRotation.Quaternion()).Rotator(); // } // else // { // DesiredRotation.Pitch = 0.f; // DesiredRotation.Yaw = FRotator::NormalizeAxis(DesiredRotation.Yaw); // DesiredRotation.Roll = 0.f; // } // } // else // { // DesiredRotation.Normalize(); // } // // // Accumulate a desired new rotation. // constexpr float AngleTolerance = 1e-3f; // // if (!CurrentRotation.Equals(DesiredRotation, AngleTolerance)) // { // // If we'd be prevented from becoming vertical, override the non-yaw rotation rates to allow the character to snap upright // if (true && bWantsToBeVertical) // { // if (FMath::IsNearlyZero(DeltaRot.Pitch)) // { // DeltaRot.Pitch = 360.0; // } // if (FMath::IsNearlyZero(DeltaRot.Roll)) // { // DeltaRot.Roll = 360.0; // } // } // // if (HasCustomGravity()) // { // FRotator GravityRelativeCurrentRotation = (GetGravityToWorldTransform() * CurrentRotation.Quaternion()).Rotator(); // FRotator GravityRelativeDesiredRotation = (GetGravityToWorldTransform() * DesiredRotation.Quaternion()).Rotator(); // // // PITCH // if (!FMath::IsNearlyEqual(GravityRelativeCurrentRotation.Pitch, GravityRelativeDesiredRotation.Pitch, AngleTolerance)) // { // GravityRelativeDesiredRotation.Pitch = FMath::FixedTurn(GravityRelativeCurrentRotation.Pitch, GravityRelativeDesiredRotation.Pitch, DeltaRot.Pitch); // } // // // YAW // if (!FMath::IsNearlyEqual(GravityRelativeCurrentRotation.Yaw, GravityRelativeDesiredRotation.Yaw, AngleTolerance)) // { // GravityRelativeDesiredRotation.Yaw = FMath::FixedTurn(GravityRelativeCurrentRotation.Yaw, GravityRelativeDesiredRotation.Yaw, DeltaRot.Yaw); // } // // // ROLL // if (!FMath::IsNearlyEqual(GravityRelativeCurrentRotation.Roll, GravityRelativeDesiredRotation.Roll, AngleTolerance)) // { // GravityRelativeDesiredRotation.Roll = FMath::FixedTurn(GravityRelativeCurrentRotation.Roll, GravityRelativeDesiredRotation.Roll, DeltaRot.Roll); // } // // DesiredRotation = (GetWorldToGravityTransform() * GravityRelativeDesiredRotation.Quaternion()).Rotator(); // } // else // { // // PITCH // if (!FMath::IsNearlyEqual(CurrentRotation.Pitch, DesiredRotation.Pitch, AngleTolerance)) // { // DesiredRotation.Pitch = FMath::FixedTurn(CurrentRotation.Pitch, DesiredRotation.Pitch, DeltaRot.Pitch); // } // // // YAW // if (!FMath::IsNearlyEqual(CurrentRotation.Yaw, DesiredRotation.Yaw, AngleTolerance)) // { // DesiredRotation.Yaw = FMath::FixedTurn(CurrentRotation.Yaw, DesiredRotation.Yaw, DeltaRot.Yaw); // } // // // ROLL // if (!FMath::IsNearlyEqual(CurrentRotation.Roll, DesiredRotation.Roll, AngleTolerance)) // { // DesiredRotation.Roll = FMath::FixedTurn(CurrentRotation.Roll, DesiredRotation.Roll, DeltaRot.Roll); // } // } // // // Set the new rotation. // DesiredRotation.DiagnosticCheckNaN(TEXT("CharacterMovementComponent::PhysicsRotation(): DesiredRotation")); // MoveUpdatedComponent(FVector::ZeroVector, DesiredRotation, /*bSweep*/ false); // } // } // // FRotator UGMS_CharacterMovementComponent::GMS_ComputeOrientToDesiredViewRotation_Implementation(const FRotator& CurrentRotation, float DeltaTime, FRotator& DeltaRotation) const // { // check(MovementSystem->GetControlSetting()); // // bool bMoving = MovementSystem->GetLocomotionState().bMoving; // // DeltaRotation.Yaw = DeltaRotation.Pitch = DeltaRotation.Roll = MovementSystem->GetControlSetting()->ViewDirectionSetting.Get().RotationInterpolationSpeed; // // float DeltaYawAngle{0.0f}; // if (!bMoving && HasAnimationRotationDeltaYawAngle(DeltaTime, DeltaYawAngle)) // { // auto NewRotation{CurrentRotation}; // NewRotation.Yaw += DeltaYawAngle; // DeltaRotation.Yaw = -1; // return NewRotation; // } // // FRotator ControllerDesiredRotation = CharacterOwner->Controller->GetDesiredRotation(); // // if (const FGMS_ViewDirectionSetting_Default* Setting = MovementSystem->GetControlSetting()->ViewDirectionSetting.GetPtr()) // { // if (bMoving || Setting->bEnableRotationWhenNotMoving) // { // auto NewRotation{CurrentRotation}; // NewRotation.Yaw = ControllerDesiredRotation.Yaw; // return NewRotation; // } // return CurrentRotation; // } // // if (const FGMS_ViewDirectionSetting_Aiming* Setting = MovementSystem->GetControlSetting()->ViewDirectionSetting.GetPtr()) // { // if (!bMoving && Setting->bEnableRotationWhenNotMoving) // { // auto NewRotation{CurrentRotation}; // NewRotation.Yaw = ControllerDesiredRotation.Yaw; // return NewRotation; // } // } // // return CurrentRotation; // } // // // bool UGMS_CharacterMovementComponent::HasAnimationRotationDeltaYawAngle_Implementation(float DeltaTime, float& OutDeltaYawAngle) const // { // UAnimInstance* AnimInstance = CharacterOwner->GetMesh()->GetAnimInstance(); // if (UGMS_MainAnimInstance* AnimInst = Cast(AnimInstance)) // { // if (AnimInst->GetOffsetRootBoneRotationMode() != EOffsetRootBoneMode::Release) // { // return false; // } // } // // const float CurveValue = AnimInstance->GetCurveValue(UGMS_Constants::RotationYawSpeedCurveName()); // // OutDeltaYawAngle = CurveValue * DeltaTime; // // return FMath::Abs(OutDeltaYawAngle) > UE_SMALL_NUMBER; // } // // // FRotator UGMS_CharacterMovementComponent::GMS_ComputeOrientToDesiredMovementRotation_Implementation(const FRotator& CurrentRotation, float DeltaTime, FRotator& DeltaRotation) const // { // return Super::ComputeOrientToMovementRotation(CurrentRotation, DeltaTime, DeltaRotation); // }