273 lines
10 KiB
C++
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;
|
|
}
|