2024-09-22 21:11:19 +00:00
// © 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/OLSBaseLayerAnimInstance.h"
# include "KismetAnimationLibrary.h"
# include "Components/OLSLocomotionComponent.h"
# include "Libraries/OLSLocomotionBPLibrary.h"
# include "GameFramework/PawnMovementComponent.h"
# include "Interfaces/OLSMoveableInterface.h"
# include "Kismet/KismetSystemLibrary.h"
# if WITH_EDITOR
# include "Misc/DataValidation.h"
# endif
# if ENABLE_LOCOMOTION_DEBUG
static TAutoConsoleVariable < bool > CVarAnimInstanceLocomotionDebug ( TEXT ( " a.AnimInstance.Locomotion.Debug " ) , false , TEXT ( " Turn on visualization debugging for Locomotion " ) ) ;
# endif
void UOLSBaseLayerAnimInstance : : NativeInitializeAnimation ( )
{
// Super::NativeInitializeAnimation();
// Don't call Super since it is empty.
if ( const TObjectPtr < APawn > owningPawn = TryGetPawnOwner ( ) )
{
OwningPawn = owningPawn ;
MovementComponent = owningPawn - > GetMovementComponent ( ) ;
MoveableInterface . SetObject ( owningPawn ) ;
MoveableInterface . SetInterface ( Cast < IOLSMoveableInterface > ( owningPawn ) ) ;
if ( MoveableInterface )
{
LocomotionComponent = MoveableInterface - > GetLocomotionComponent ( ) ;
}
}
}
void UOLSBaseLayerAnimInstance : : NativeUninitializeAnimation ( )
{
// Super::NativeUninitializeAnimation();
// Don't call Super since it is empty.
if ( LocomotionComponent )
{
LocomotionComponent - > GetOnStanceChangedNativeDelegate ( ) . RemoveAll ( this ) ;
LocomotionComponent - > GetOnGaitChangedNativeDelegate ( ) . RemoveAll ( this ) ;
LocomotionComponent - > GetOnRotationModeChangedNativeDelegate ( ) . RemoveAll ( this ) ;
}
}
void UOLSBaseLayerAnimInstance : : NativeBeginPlay ( )
{
Super : : NativeBeginPlay ( ) ;
if ( LocomotionComponent )
{
LocomotionComponent - > GetOnStanceChangedNativeDelegate ( ) . AddWeakLambda (
this , [ this ] ( const EOLSStance & prevStance )
{
if ( LocomotionComponent )
{
Stance = LocomotionComponent - > GetStance ( ) ;
}
} ) ;
LocomotionComponent - > GetOnDesiredGaitChangedNativeDelegate ( ) . AddWeakLambda (
this , [ this ] ( const EOLSGait & prevDesiredGait )
{
if ( LocomotionComponent )
{
DesiredGait = LocomotionComponent - > GetDesiredGait ( ) ;
}
} ) ;
LocomotionComponent - > GetOnGaitChangedNativeDelegate ( ) . AddWeakLambda (
this , [ this ] ( const EOLSGait & prevGait )
{
if ( LocomotionComponent )
{
PrevGait = prevGait ;
Gait = LocomotionComponent - > GetGait ( ) ;
bHasGaitChanged = true ;
}
} ) ;
LocomotionComponent - > GetOnRotationModeChangedNativeDelegate ( ) . AddWeakLambda (
this , [ this ] ( const EOLSRotationMode & prevRotationMode )
{
if ( LocomotionComponent )
{
RotationMode = LocomotionComponent - > GetRotationMode ( ) ;
}
} ) ;
}
}
void UOLSBaseLayerAnimInstance : : NativeUpdateAnimation ( float deltaSeconds )
{
// Super::NativeUpdateAnimation(deltaSeconds);
// Don't call Super since it is empty.
if ( OwningPawn & & MoveableInterface & & MovementComponent )
{
NativeUpdateLocationData ( OwningPawn , deltaSeconds ) ;
NativeUpdateRotationData ( OwningPawn , deltaSeconds ) ;
NativeUpdateVelocityData ( MoveableInterface , OwningPawn , deltaSeconds ) ;
NativeUpdateAccelerationData ( OwningPawn , deltaSeconds ) ;
NativeUpdateCharacterStateData ( MoveableInterface , MovementComponent , deltaSeconds ) ;
NativeUpdateAimingData ( OwningPawn , deltaSeconds ) ;
}
}
void UOLSBaseLayerAnimInstance : : NativeThreadSafeUpdateAnimation ( float deltaSeconds )
{
// Super::NativeThreadSafeUpdateAnimation(deltaSeconds);
// Don't call Super since it is empty.
NativeThreadSafeUpdateLocationData ( deltaSeconds ) ;
NativeThreadSafeUpdateRotationData ( deltaSeconds ) ;
NativeThreadSafeUpdateVelocityData ( deltaSeconds ) ;
NativeThreadSafeUpdateAccelerationData ( deltaSeconds ) ;
NativeThreadSafeUpdateWallDetectionHeuristic ( deltaSeconds ) ;
NativeThreadSafeUpdateCharacterStateData ( deltaSeconds ) ;
NativeThreadSafeUpdateAimingData ( deltaSeconds ) ;
2024-10-23 22:41:23 +00:00
NativeThreadSafeUpdateRootYawOffset ( deltaSeconds ) ;
2024-09-22 21:11:19 +00:00
bIsFirstUpdate = false ;
}
void UOLSBaseLayerAnimInstance : : NativePostEvaluateAnimation ( )
{
// Don't call Super since it's empty.
# if WITH_EDITOR
const TObjectPtr < AActor > owningActor = GetOwningActor ( ) ;
if ( owningActor )
{
const FVector & actorLocation = owningActor - > GetActorLocation ( ) ;
const FVector & actorForwardDir = owningActor - > GetActorForwardVector ( ) * 100.f ;
UKismetSystemLibrary : : DrawDebugArrow ( this , actorLocation , actorLocation + actorForwardDir , 0.f , FLinearColor : : Black , 0.f , 1.f ) ;
const TObjectPtr < USkeletalMeshComponent > owningComponent = GetOwningComponent ( ) ;
if ( owningComponent )
{
const FVector & rightDir = UKismetMathLibrary : : GetRightVector ( owningComponent - > GetSocketRotation ( SKEL_RootBoneName ) ) * 100.f ;
UKismetSystemLibrary : : DrawDebugArrow ( this , actorLocation , actorLocation + rightDir , 0.f , FLinearColor : : Red , 0.f , 1.f ) ;
}
}
# endif
}
void UOLSBaseLayerAnimInstance : : NativeUpdateRotationData ( APawn * owningPawn , const float deltaSeconds )
{
OwningPawnRotation = owningPawn - > GetActorRotation ( ) ;
}
void UOLSBaseLayerAnimInstance : : NativeUpdateLocationData ( APawn * owningPawn , const float deltaSeconds )
{
OwningPawnLocation = owningPawn - > GetActorLocation ( ) ;
}
void UOLSBaseLayerAnimInstance : : NativeUpdateVelocityData ( const TScriptInterface < IOLSMoveableInterface > & moveableInterface ,
APawn * owningPawn , const float deltaSeconds )
{
OwningPawnVelocity = owningPawn - > GetVelocity ( ) ;
}
void UOLSBaseLayerAnimInstance : : NativeUpdateAccelerationData ( APawn * owningPawn , const float deltaSeconds )
{
OwningPawnAcceleration = MoveableInterface - > GetCurrentAcceleration ( ) ;
}
void UOLSBaseLayerAnimInstance : : NativeUpdateCharacterStateData (
const TScriptInterface < IOLSMoveableInterface > & moveableInterface , UPawnMovementComponent * movementComponent ,
const float deltaSeconds )
{
OwningPawnMovementMode = moveableInterface - > GetMovementMode ( ) ;
bIsOwningPawnOnGround = movementComponent - > IsMovingOnGround ( ) ;
bIsOwningPawnCrouching = movementComponent - > IsCrouching ( ) ;
2024-10-23 22:41:23 +00:00
bIsOwningOrientRotationToMovement = moveableInterface - > IsOrientRotationToMovement ( ) ;
2024-09-22 21:11:19 +00:00
OwningPawnGravityZ = movementComponent - > GetGravityZ ( ) ;
OwningPawnMaxSpeed = movementComponent - > GetMaxSpeed ( ) ;
}
void UOLSBaseLayerAnimInstance : : NativeUpdateAimingData ( APawn * owningPawn , const float deltaSeconds )
{
OwningPawnAimRotation = owningPawn - > GetBaseAimRotation ( ) ;
}
void UOLSBaseLayerAnimInstance : : NativeThreadSafeUpdateRotationData ( const float deltaSeconds )
{
if ( bIsFirstUpdate )
{
YawDeltaSinceLastUpdate = 0.f ;
YawDeltaSpeed = 0.f ;
return ;
}
YawDeltaSinceLastUpdate = OwningPawnRotation . Yaw - WorldRotation . Yaw ;
YawDeltaSpeed = UKismetMathLibrary : : SafeDivide ( YawDeltaSinceLastUpdate , deltaSeconds ) ;
AdditiveLeanAngle = YawDeltaSpeed * ( ( bIsOwningPawnCrouching ) ? .025f : .0375f ) ;
WorldRotation = OwningPawnRotation ;
// Call custom logic on blueprint.
BlueprintThreadSafeUpdateRotationData ( deltaSeconds ) ;
}
void UOLSBaseLayerAnimInstance : : NativeThreadSafeUpdateLocationData ( const float deltaSeconds )
{
if ( bIsFirstUpdate )
{
DisplacementSinceLastUpdate = 0.f ;
DisplacementSpeed = 0.f ;
return ;
}
DisplacementSinceLastUpdate = ( OwningPawnLocation - WorldLocation ) . Size2D ( ) ;
WorldLocation = OwningPawnLocation ;
DisplacementSpeed = UKismetMathLibrary : : SafeDivide ( DisplacementSinceLastUpdate , deltaSeconds ) ;
// Call custom logic on blueprint.
BlueprintThreadSafeUpdateLocationData ( deltaSeconds ) ;
}
void UOLSBaseLayerAnimInstance : : NativeThreadSafeUpdateVelocityData ( const float deltaSeconds )
{
const bool wasMovingLastUpdate = ! LocalVelocity2D . IsNearlyZero ( 1.e-4 f ) ;
if ( wasMovingLastUpdate )
{
StopLocalVelocityCardinalDirection = LocalVelocityDirection ;
}
WorldVelocity = OwningPawnVelocity ;
const FVector worldVelocity2D = WorldVelocity * FVector ( 1.f , 1.f , 0.f ) ;
LocalVelocity2D = UKismetMathLibrary : : LessLess_VectorRotator ( worldVelocity2D , WorldRotation ) ;
LocalVelocityDirectionAngle = UKismetAnimationLibrary : : CalculateDirection ( worldVelocity2D , WorldRotation ) ;
2024-10-23 22:41:23 +00:00
LocalVelocityDirectionAngleWithOffset = LocalVelocityDirectionAngle - RootYawOffset ;
LocalVelocityDirection = UOLSLocomotionBPLibrary : : SelectCardinalDirectionFromAngle ( LocalVelocityDirectionAngleWithOffset ,
CardinalDirectionDeadZone ,
LocalVelocityDirection ,
wasMovingLastUpdate ) ;
LocalVelocityDirectionNoOffset = UOLSLocomotionBPLibrary : : SelectCardinalDirectionFromAngle (
LocalVelocityDirectionAngle ,
CardinalDirectionDeadZone ,
LocalVelocityDirection ,
wasMovingLastUpdate ) ;
2024-09-22 21:11:19 +00:00
bHasVelocity = ! FMath : : IsNearlyZero ( LocalVelocity2D . SizeSquared2D ( ) ) ;
// Call custom logic on blueprint.
BlueprintThreadSafeUpdateVelocityData ( deltaSeconds ) ;
}
void UOLSBaseLayerAnimInstance : : NativeThreadSafeUpdateAccelerationData ( const float deltaSeconds )
{
const FVector worldAcceleration2D = OwningPawnAcceleration * FVector ( 1.f , 1.f , 0.f ) ;
LocalAcceleration2D = UKismetMathLibrary : : LessLess_VectorRotator ( worldAcceleration2D , WorldRotation ) ;
bHasAcceleration = ( ! FMath : : IsNearlyZero ( LocalAcceleration2D . SizeSquared2D ( ) , .000001f ) ) ;
PivotDirection2D =
UKismetMathLibrary : : Normal ( UKismetMathLibrary : : VLerp ( PivotDirection2D , UKismetMathLibrary : : Normal ( worldAcceleration2D ) , .5f ) ) ;
CardinalDirectionFromAcceleration = ( IsLookingOrAimingDirection ( )
? UOLSLocomotionBPLibrary : : GetOppositeCardinalDirectional (
UOLSLocomotionBPLibrary : : SelectCardinalDirectionFromAngle (
UKismetAnimationLibrary : : CalculateDirection ( PivotDirection2D , WorldRotation ) ,
CardinalDirectionDeadZone , EOLSCardinalDirection : : EForward ) )
: EOLSCardinalDirection : : EBackward ) ;
// Call custom logic on blueprint.
BlueprintThreadSafeUpdateAccelerationData ( deltaSeconds ) ;
}
void UOLSBaseLayerAnimInstance : : NativeThreadSafeUpdateWallDetectionHeuristic ( const float deltaSeconds )
{
const bool hasAccelerationPassedThreshold = ( LocalAcceleration2D . Size2D ( ) > .1f ) ;
const bool hasVelocityBelowThreshold = ( LocalVelocity2D . Size2D ( ) < 200.f ) ;
const FVector normalLocalAcceleration2D = UKismetMathLibrary : : Normal ( LocalAcceleration2D ) ;
const FVector normalLocalVelocity2D = UKismetMathLibrary : : Normal ( LocalVelocity2D ) ;
const bool isDotProductInRange = UKismetMathLibrary : : InRange_FloatFloat (
UKismetMathLibrary : : Dot_VectorVector (
normalLocalAcceleration2D , normalLocalVelocity2D ) ,
- .6f , .6f ) ;
bIsRunningIntoWall = hasAccelerationPassedThreshold & & hasVelocityBelowThreshold & & isDotProductInRange ;
// Call custom logic on blueprint.
BlueprintThreadSafeUpdateWallDetectionHeuristic ( deltaSeconds ) ;
}
void UOLSBaseLayerAnimInstance : : NativeThreadSafeUpdateCharacterStateData ( const float deltaSeconds )
{
// Locomotion Component Data.
{
bHasGaitChanged = ( Gait ! = LastGait ) ;
LastGait = Gait ;
bHasRotationModeChanged = ( RotationMode ! = LastRotationMode ) ;
LastRotationMode = RotationMode ;
}
// Crouch state.
{
const bool wasCrouchingLastUpdate = bIsCrouching ;
bIsCrouching = bIsOwningPawnCrouching ;
bHasCrouchStateChanged = ( bIsCrouching ! = wasCrouchingLastUpdate ) ;
}
// ADS state.
{
bHasADSStateChanged = ( bGameplayTag_IsADS ! = bWasADSLastUpdate ) ;
bWasADSLastUpdate = bGameplayTag_IsADS ;
}
// Weapon fired state.
{
TimeSinceFiredWeapon = ( bGameplayTag_IsFiring ) ? 0.f : TimeSinceFiredWeapon + deltaSeconds ;
}
// In air state.
{
bIsJumping = false ;
bIsFalling = false ;
if ( OwningPawnMovementMode = = MOVE_Falling )
{
if ( WorldVelocity . Z > 0.f )
{
bIsJumping = true ;
}
else
{
bIsFalling = true ;
}
// Update Jump Fall Data.
{
if ( bIsJumping )
{
TimeToJumpApex = UKismetMathLibrary : : SafeDivide ( 0.f - WorldVelocity . Z , OwningPawnGravityZ ) ;
}
else
{
TimeToJumpApex = 0.f ;
}
}
}
}
// Call custom logic on blueprint.
BlueprintThreadSafeUpdateCharacterData ( deltaSeconds ) ;
}
void UOLSBaseLayerAnimInstance : : NativeThreadSafeUpdateAimingData ( const float deltaSeconds )
{
AimPitch = UKismetMathLibrary : : NormalizeAxis ( OwningPawnRotation . Pitch ) ;
// Call custom logic on blueprint.
BlueprintThreadSafeUpdateAimingData ( deltaSeconds ) ;
}
2024-10-23 22:41:23 +00:00
void UOLSBaseLayerAnimInstance : : NativeThreadSafeUpdateRootYawOffset ( const float deltaSeconds )
{
if ( RootYawOffsetMode = = EOLSRootYawOffsetMode : : EAccumulate )
{
SetRootYawOffset ( RootYawOffset - YawDeltaSinceLastUpdate ) ;
}
if ( RootYawOffsetMode = = EOLSRootYawOffsetMode : : EBlendOut )
{
SetRootYawOffset (
UKismetMathLibrary : : FloatSpringInterp ( RootYawOffset ,
0.f ,
2024-10-24 02:34:02 +00:00
RootYawOffsetSpringState ,
2024-10-23 22:41:23 +00:00
80.f ,
1.f ,
deltaSeconds ,
1.f ,
.5f ) ) ;
}
RootYawOffsetMode = EOLSRootYawOffsetMode : : EBlendOut ;
}
2024-09-22 21:11:19 +00:00
UPawnMovementComponent * UOLSBaseLayerAnimInstance : : GetMovementComponent ( ) const
{
return MovementComponent ;
}
const FVector & UOLSBaseLayerAnimInstance : : GetWorldVelocity ( ) const
{
return WorldVelocity ;
}
const float & UOLSBaseLayerAnimInstance : : GetLocalVelocityDirectionAngle ( ) const
{
return LocalVelocityDirectionAngle ;
}
const float & UOLSBaseLayerAnimInstance : : GetDisplacementSpeed ( ) const
{
return DisplacementSpeed ;
}
const FVector & UOLSBaseLayerAnimInstance : : GetLocalAcceleration2D ( ) const
{
return LocalAcceleration2D ;
}
bool UOLSBaseLayerAnimInstance : : IsLookingOrAimingDirection ( ) const
{
return ( IsLookingDirection ( ) | | IsAimingDirection ( ) ) ;
}
bool UOLSBaseLayerAnimInstance : : IsVelocityOrLookingDirection ( ) const
{
return ( IsVelocityDirection ( ) | | IsLookingDirection ( ) ) ;
}
bool UOLSBaseLayerAnimInstance : : IsVelocityOrAimingDirection ( ) const
{
return ( IsVelocityDirection ( ) | | IsAimingDirection ( ) ) ;
}
bool UOLSBaseLayerAnimInstance : : IsAimingDirection ( ) const
{
return ( RotationMode = = EOLSRotationMode : : EAiming ) ;
}
bool UOLSBaseLayerAnimInstance : : IsLookingDirection ( ) const
{
return ( RotationMode = = EOLSRotationMode : : ELookingDirection ) ;
}
bool UOLSBaseLayerAnimInstance : : IsVelocityDirection ( ) const
{
return ( RotationMode = = EOLSRotationMode : : EVelocityDirection ) ;
}
bool UOLSBaseLayerAnimInstance : : IsCrouching ( ) const
{
return bIsCrouching ;
}
bool UOLSBaseLayerAnimInstance : : HasVelocity ( ) const
{
return bHasVelocity ;
}
bool UOLSBaseLayerAnimInstance : : HasAcceleration ( ) const
{
return bHasAcceleration ;
}
bool UOLSBaseLayerAnimInstance : : ShouldDistanceMatchStop ( ) const
{
return HasVelocity ( ) & & ! HasAcceleration ( ) ;
}
bool UOLSBaseLayerAnimInstance : : IsMovingPerpendicularToInitialPivot ( ) const
{
const bool isPivotFwdOrBwd = ( PivotInitialDirection = = EOLSCardinalDirection : : EForward | | PivotInitialDirection = = EOLSCardinalDirection : : EBackward ) ;
const bool isVelocityFwdOrBwd = ( LocalVelocityDirection = = EOLSCardinalDirection : : EForward | | LocalVelocityDirection = = EOLSCardinalDirection : : EBackward ) ;
const bool isPivotLeftOrRight = ( PivotInitialDirection = = EOLSCardinalDirection : : ELeft | | PivotInitialDirection = = EOLSCardinalDirection : : ERight ) ;
const bool isVelocityLeftOrRight = ( LocalVelocityDirection = = EOLSCardinalDirection : : ELeft | | LocalVelocityDirection = = EOLSCardinalDirection : : ERight ) ;
return ( isPivotFwdOrBwd & & ! isVelocityFwdOrBwd ) | | ( isPivotLeftOrRight & & ! isVelocityLeftOrRight ) ;
}
const EOLSRotationMode & UOLSBaseLayerAnimInstance : : GetRotationMode ( ) const
{
return RotationMode ;
}
const float & UOLSBaseLayerAnimInstance : : GetOwningPawnMaxSpeed ( ) const
{
return OwningPawnMaxSpeed ;
}
2024-10-23 22:41:23 +00:00
void UOLSBaseLayerAnimInstance : : SetRootYawOffset ( const float rootYawOffset )
{
if ( ! bEnableRootYawOffset )
{
RootYawOffset = 0.f ;
AimYaw = 0.f ;
return ;
}
const float normalRootYawOffset = UKismetMathLibrary : : NormalizeAxis ( rootYawOffset ) ;
2024-10-26 00:55:47 +00:00
RootYawOffset = ( RootYawOffsetAngleClamp . X = = RootYawOffsetAngleClamp . Y ) ? normalRootYawOffset : FMath : : Clamp ( normalRootYawOffset , RootYawOffsetAngleClamp . X , RootYawOffsetAngleClamp . Y ) ;
2024-10-23 22:41:23 +00:00
AimYaw = RootYawOffset * - 1.f ;
}
void UOLSBaseLayerAnimInstance : : ProcessTurnYawCurve ( )
{
float previousTurnYawCurveValue = TurnYawCurveValue ;
const float turnYawWeightCurveValue = GetCurveValue ( TurnYawWeightCurveName ) ;
if ( FMath : : IsNearlyZero ( turnYawWeightCurveValue , 0.0001f ) )
{
TurnYawCurveValue = 0.f ;
previousTurnYawCurveValue = 0.f ;
return ;
}
const float remainingTurnYawCurveValue = GetCurveValue ( RemainingTurnYawCurveName ) ;
TurnYawCurveValue = UKismetMathLibrary : : SafeDivide ( remainingTurnYawCurveValue , turnYawWeightCurveValue ) ;
// Avoid applying the curve delta when the curve first becomes relevant. E.g.
// When a turn animation starts, the previous curve value will be 0 and the current value will be 90,
// but no actual rotation has happened yet.
if ( previousTurnYawCurveValue ! = 0.f )
{
// Reduce the target yaw offset by the amount of rotation from the turn animation.
SetRootYawOffset ( RootYawOffset - ( TurnYawCurveValue - previousTurnYawCurveValue ) ) ;
}
}
void UOLSBaseLayerAnimInstance : : ProcessTurnYawCurve_ForwardFacing ( )
{
float previousTurnYawCurveValue = TurnYawCurveValue ;
const float turnYawWeightCurveValue = GetCurveValue ( TurnYawWeightCurveName ) ;
if ( FMath : : IsNearlyZero ( turnYawWeightCurveValue , 0.0001f ) )
{
TurnYawCurveValue = 0.f ;
previousTurnYawCurveValue = 0.f ;
// When the animation blends in, we could have near-zero weights.
// When this value is goes up, and then down to 0, we know.
2024-10-24 02:34:02 +00:00
if ( MaxTurnYawValue ! = 0.f )
2024-10-23 22:41:23 +00:00
{
bHasReachedEndTurn = true ;
}
}
2024-10-24 02:34:02 +00:00
else
2024-10-23 22:41:23 +00:00
{
2024-10-24 02:34:02 +00:00
const float remainingTurnYawCurveValue = GetCurveValue ( RemainingTurnYawCurveName ) ;
TurnYawCurveValue = UKismetMathLibrary : : SafeDivide ( remainingTurnYawCurveValue , turnYawWeightCurveValue ) ;
2024-10-23 22:41:23 +00:00
2024-10-24 02:34:02 +00:00
if ( FMath : : Abs ( TurnYawCurveValue ) > FMath : : Abs ( MaxTurnYawValue ) )
{
MaxTurnYawValue = TurnYawCurveValue ;
}
// Avoid applying the curve delta when the curve first becomes relevant. E.g.
// When a turn animation starts, the previous curve value will be 0 and the current value will be 90,
// but no actual rotation has happened yet.
if ( previousTurnYawCurveValue ! = 0.f )
{
const float actualAngle = UKismetMathLibrary : : SafeDivide ( LocalVelocityDirectionAngleWithOffset ,
TurnYawCurveValue ) * ( TurnYawCurveValue - previousTurnYawCurveValue ) ;
const float minAngle = FMath : : Abs ( LocalVelocityDirectionAngleWithOffset ) * - 1.f ;
const float maxAngle = FMath : : Abs ( LocalVelocityDirectionAngleWithOffset ) ;
// Reduce the target yaw offset by the amount of rotation from the turn animation.
SetRootYawOffset ( RootYawOffset - FMath : : Clamp ( actualAngle , minAngle , maxAngle ) ) ;
}
}
2024-10-23 22:41:23 +00:00
}
2024-09-22 21:11:19 +00:00
float UOLSBaseLayerAnimInstance : : CalculateMeshSpaceBlendWeight ( const FName localSpaceLayerCurveName ) const
{
// If this condition fails so MeshSpace will be prioritized.
if ( localSpaceLayerCurveName . IsNone ( ) )
{
return 1.f ;
}
const int32 localSpaceCurveValue = FMath : : FloorToInt ( GetCurveValue ( localSpaceLayerCurveName ) ) ;
return 1 - localSpaceCurveValue ;
}
UOLSLocomotionComponent * UOLSBaseLayerAnimInstance : : ThreadSafeGetLocomotionComponent ( ) const
{
return LocomotionComponent ;
}