// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action. #include "AnimInstances/OLSBaseLinkedLayerAnimInstance.h" #include "AnimInstances/OLSBaseLayerAnimInstance.h" void UOLSBaseLinkedLayerAnimInstance::NativeInitializeAnimation() { // Super::NativeInitializeAnimation(); // Don't call Super since it is empty. BaseMainAnimInstance = Cast(GetOwningComponent()->GetAnimInstance()); } void UOLSBaseLinkedLayerAnimInstance::NativeUpdateAnimation(float deltaSeconds) { // Super::NativeUpdateAnimation(deltaSeconds); // Don't call Super since it is empty. NativeUpdateEssentialValues(deltaSeconds); } void UOLSBaseLinkedLayerAnimInstance::NativeThreadSafeUpdateAnimation(float deltaSeconds) { // Super::NativeThreadSafeUpdateAnimation(deltaSeconds); // Don't call Super since it is empty. NativeThreadSafeUpdateLocomotionStateData(deltaSeconds); NativeUpdateSkeletonControlData(deltaSeconds); } void UOLSBaseLinkedLayerAnimInstance::NativePostEvaluateAnimation() { // Don't call Super since it's empty. } void UOLSBaseLinkedLayerAnimInstance::NativeUpdateEssentialValues(const float deltaSeconds) { if (BaseMainAnimInstance) { WorldVelocity = BaseMainAnimInstance->GetWorldVelocity(); LocalVelocityDirectionAngle = BaseMainAnimInstance->GetLocalVelocityDirectionAngle(); DisplacementSpeed = BaseMainAnimInstance->GetDisplacementSpeed(); LocalAcceleration2D = BaseMainAnimInstance->GetLocalAcceleration2D(); bIsLookingOrAimingDirection = BaseMainAnimInstance->IsLookingOrAimingDirection(); bIsVelocityOrAimingDirection = BaseMainAnimInstance->IsVelocityOrAimingDirection(); bIsCrouching = BaseMainAnimInstance->IsCrouching(); bHasAcceleration = BaseMainAnimInstance->HasAcceleration(); bHasVelocity = BaseMainAnimInstance->HasVelocity(); RotationMode = BaseMainAnimInstance->GetRotationMode(); OwningPawnMaxSpeed = BaseMainAnimInstance->GetOwningPawnMaxSpeed(); } } void UOLSBaseLinkedLayerAnimInstance::NativeUpdateSkeletonControlData(const float deltaSeconds) { OrientationWarpingAlpha = GetCurveValue(EnableOrientationWarpingName); } void UOLSBaseLinkedLayerAnimInstance::NativeThreadSafeUpdateLocomotionStateData(const float deltaSeconds) { HipDirection = (bUseHipDirection ? GetHipDirection() : EOLSHipDirection::EForward); // Call custom logic on blueprint. BlueprintThreadSafeUpdateLocomotionStateData(deltaSeconds); } EOLSHipDirection UOLSBaseLinkedLayerAnimInstance::GetHipDirection() const { if (!bIsLookingOrAimingDirection) { return EOLSHipDirection::EForward; } const bool isHipForward = UKismetMathLibrary::InRange_FloatFloat(FMath::Abs(LocalVelocityDirectionAngle), HipDirectionAngleClamp.X + HipDirectionAngleClamp. Y, HipDirectionAngleClamp.Y + HipDirectionBuffer) && UKismetMathLibrary::InRange_FloatFloat(FMath::Abs(LocalVelocityDirectionAngle), HipDirectionAngleClamp.X - HipDirectionAngleClamp.Y, HipDirectionAngleClamp.Y + HipDirectionBuffer); return (isHipForward) ? EOLSHipDirection::EForward : EOLSHipDirection::EBackward; } const FOLSStanceAnimSets& UOLSBaseLinkedLayerAnimInstance::GetStanceAnimSets(const bool isCrouching) const { return (isCrouching ? Crouching_AnimSets : Standing_AnimSets); } const FOLSGaitAnimSets& UOLSBaseLinkedLayerAnimInstance::GetGaitAnimSets(const bool isCrouching, const EOLSGait& locomotionState) const { const FOLSStanceAnimSets& stanceAnimSets = GetStanceAnimSets(isCrouching); return (isCrouching) ? stanceAnimSets.GetGaitAnimSetByGait(EOLSGait::EWalk) : stanceAnimSets.GetGaitAnimSetByGait(locomotionState); } UAnimSequence* UOLSBaseLinkedLayerAnimInstance::SelectIdleAnimation(const bool isCrouching) const { return GetStanceAnimSets(isCrouching).GetIdleAnimation(); } UAnimSequence* UOLSBaseLinkedLayerAnimInstance::SelectIdleEntryAnimation(const bool isCrouching) const { return GetStanceAnimSets(isCrouching).GetIdleExitAnimation(); } UAnimSequence* UOLSBaseLinkedLayerAnimInstance::SelectIdleBreakAnimation(const bool isCrouching) const { return GetStanceAnimSets(isCrouching).GetRandomIdleBreakAnimation(); } UAnimSequence* UOLSBaseLinkedLayerAnimInstance::SelectTurnInPlaceAnimation( const bool isCrouching, const float direction) const { return GetStanceAnimSets(isCrouching).GetTurnInPlaceAnimation(direction); } UAnimSequence* UOLSBaseLinkedLayerAnimInstance::SelectStartCycleAnimation(const bool isCrouching, const bool isAiming, const EOLSGait gait, const EOLSCardinalDirection velocityDirection, const EOLSHipDirection hipDirection, const float angle) const { if (isAiming) { return GetGaitAnimSets(isCrouching, gait).GaitAnimSet_CameraFacing.GetStartCycleFromHipDirection(hipDirection). GetMovementAnimationByCardinalDirection(velocityDirection); } return GetGaitAnimSets(isCrouching, gait).GaitAnimSet_ForwardFacing.StartCycle. GetMovementAnimationByAngle(velocityDirection, angle); } UAnimSequence* UOLSBaseLinkedLayerAnimInstance::SelectCycleAnimation(const bool isCrouching, const bool isAiming, const EOLSGait gait, const EOLSCardinalDirection velocityDirection, const EOLSHipDirection hipDirection) const { if (isAiming) { return GetGaitAnimSets(isCrouching, gait).GaitAnimSet_CameraFacing.GetCycleFromHipDirection(hipDirection). GetMovementAnimationByCardinalDirection(velocityDirection); } return GetGaitAnimSets(isCrouching, gait).GaitAnimSet_ForwardFacing.Cycle; } UAnimSequence* UOLSBaseLinkedLayerAnimInstance::SelectPivotAnimation(const bool isCrouching, const bool isAiming, const EOLSGait gait, const EOLSCardinalDirection velocityDirection, const EOLSHipDirection hipDirection, const float angle) const { if (isAiming) { return GetGaitAnimSets(isCrouching, gait).GaitAnimSet_CameraFacing.GetPivotFromHipDirection(hipDirection). GetMovementAnimationByCardinalDirection(velocityDirection); } return GetGaitAnimSets(isCrouching, gait).GaitAnimSet_ForwardFacing.Pivot.GetBackwardLeftRightByAngle(angle); } UAnimSequence* UOLSBaseLinkedLayerAnimInstance::SelectStopCycleAnimation(const bool isCrouching, const bool isAiming, const EOLSGait gait, const EOLSCardinalDirection velocityDirection, const EOLSHipDirection hipDirection) const { if (isAiming) { return GetGaitAnimSets(isCrouching, gait). GaitAnimSet_CameraFacing.GetStopCycleFromHipDirection(hipDirection). GetMovementAnimationByCardinalDirection(velocityDirection); } return GetGaitAnimSets(isCrouching, gait).GaitAnimSet_ForwardFacing.StopCycle; } FVector2D UOLSBaseLinkedLayerAnimInstance::SelectPlayRateByLocomotionState( const bool isCrouching, const bool isAiming, const EOLSGait gait, const EOLSLocomotionStatePlayRate locomotionState) const { FVector2D result = FVector2D::ZeroVector; if (isAiming) { const FOLSGaitAnimSet_CameraFacing& gaitAnimSet = GetGaitAnimSets(isCrouching, gait).GaitAnimSet_CameraFacing; gaitAnimSet.GetPlayRateByLocomotionState(locomotionState, result); return result; } const FOLSGaitAnimSet_ForwardFacing& gaitAnimSet = GetGaitAnimSets(isCrouching, gait).GaitAnimSet_ForwardFacing; gaitAnimSet.GetPlayRateByLocomotionState(locomotionState, result); return result; } bool UOLSBaseLinkedLayerAnimInstance::CanPlayIdleBreakAnimation(const bool isCrouching) const { return GetStanceAnimSets(isCrouching).CanPlayIdleBreakAnimation(); } void UOLSBaseLinkedLayerAnimInstance::ProcessIdleBreakTransitionLogic(const bool isCrouching, const float deltaSeconds) { if (CanPlayIdleBreakAnimation(isCrouching)) { TimeUntilNextIdleBreak -= deltaSeconds; return; } ResetIdleBreakTransitionLogic(); } void UOLSBaseLinkedLayerAnimInstance::ResetIdleBreakTransitionLogic() { TimeUntilNextIdleBreak = IdleBreakDelayTime; } void UOLSBaseLinkedLayerAnimInstance::DetermineIdleBreakDelayTime() { IdleBreakDelayTime = 6 + FMath::TruncToInt32(FMath::Abs(WorldVelocity.X + WorldVelocity.Y)) & 10; } void UOLSBaseLinkedLayerAnimInstance::ProcessTurnInPlaceTransitionLogic(const float angle, const float turnRate, const float deltaSeconds) { switch (RotationMode) { case EOLSRotationMode::EVelocityDirection: { bCanRotateInPlace = false; bCanTurnInPlace = false; TurnInPlaceDelayTime = 0.f; break; } case EOLSRotationMode::ELookingDirection: { bCanRotateInPlace = false; const float absAngle = FMath::Abs(angle); if (absAngle > 45.f && turnRate < 50.f) { TurnInPlaceDelayTime += deltaSeconds; bCanTurnInPlace = TurnInPlaceDelayTime > UKismetMathLibrary::MapRangeClamped( absAngle, 45.f, 180.f, 1.f, 0.f); break; } bCanTurnInPlace = false; break; } case EOLSRotationMode::EAiming: { bCanTurnInPlace = false; TurnInPlaceDelayTime = 0.f; const float absAngle = FMath::Abs(angle); bCanRotateInPlace = (absAngle > 50.f); break; } } } UOLSBaseLayerAnimInstance* UOLSBaseLinkedLayerAnimInstance::GetBaseMainAnimInstance() const { return BaseMainAnimInstance; }