OLS/Source/OLSAnimation/Private/AnimInstances/OLSBaseLinkedLayerAnimInstance.cpp
2024-09-22 17:11:19 -04:00

273 lines
10 KiB
C++

// © 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<UOLSBaseLayerAnimInstance>(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;
}
FOLSStanceAnimSets UOLSBaseLinkedLayerAnimInstance::GetStanceAnimSets(const bool isCrouching) const
{
return (isCrouching ? CrouchingAnimSets : StandingAnimSets);
}
const FOLSGaitAnimSets& UOLSBaseLinkedLayerAnimInstance::GetGaitAnimSets(
const bool isCrouching, const EOLSGait& locomotionState) const
{
//@TODO: add nullptr log.
return *GetStanceAnimSets(isCrouching).SelectGaitAnimSetByGait(locomotionState);
}
UAnimSequence* UOLSBaseLinkedLayerAnimInstance::SelectIdleAnimation(const bool isCrouching, const bool isAiming) const
{
return GetStanceAnimSets(isCrouching).GetIdleAnimation(isAiming);
}
UAnimSequence* UOLSBaseLinkedLayerAnimInstance::SelectIdleEntryAnimation(const bool isCrouching) const
{
return GetStanceAnimSets(isCrouching).GetIdleEntryAnimation();
}
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;
}