Refactored camera direction

This commit is contained in:
mrlee207 2025-08-05 10:24:11 +07:00
parent 43c3d02f0a
commit c90b733a3d
13 changed files with 345 additions and 180 deletions

View File

@ -244,7 +244,7 @@ void UOLSBaseLayerAnimInstance::NativeThreadSafeUpdateVelocityData(const float d
const bool wasMovingLastUpdate = !LocalVelocity2D.IsNearlyZero(1.e-4f);
if (wasMovingLastUpdate)
{
StopLocalVelocityCardinalDirection = LocalVelocityDirection;
StopLocalVelocityDirection = LocalVelocityDirection;
}
WorldVelocity = OwningPawnVelocity;
@ -255,16 +255,13 @@ void UOLSBaseLayerAnimInstance::NativeThreadSafeUpdateVelocityData(const float d
LocalVelocityDirectionAngle = UKismetAnimationLibrary::CalculateDirection(worldVelocity2D, WorldRotation);
LocalVelocityDirectionAngleWithOffset = LocalVelocityDirectionAngle - RootYawOffset;
LocalVelocityDirection = UOLSLocomotionBPLibrary::SelectCardinalDirectionFromAngle(LocalVelocityDirectionAngleWithOffset,
CardinalDirectionDeadZone,
LocalVelocityDirection,
wasMovingLastUpdate);
GetMovementDirectionThresholds(LocalVelocityDirection, MovementDirectionThresholds);
LocalVelocityDirectionNoOffset = UOLSLocomotionBPLibrary::SelectCardinalDirectionFromAngle(
LocalVelocityDirectionAngle,
CardinalDirectionDeadZone,
LocalVelocityDirection,
wasMovingLastUpdate);
LocalVelocityDirection = UOLSLocomotionBPLibrary::SelectMovementDirectionFromAngle(
LocalVelocityDirectionAngleWithOffset, RotationMode, Gait, MovementDirectionBias, MovementDirectionThresholds);
LocalVelocityDirectionNoOffset = UOLSLocomotionBPLibrary::SelectMovementDirectionFromAngle(
LocalVelocityDirectionAngle, RotationMode, Gait, MovementDirectionBias, MovementDirectionThresholds);
bHasVelocity = (LocalVelocity2D.SizeSquared2D() > KINDA_SMALL_NUMBER);
@ -281,14 +278,21 @@ void UOLSBaseLayerAnimInstance::NativeThreadSafeUpdateAccelerationData(const flo
bHasAcceleration = (LocalAcceleration2D.SizeSquared2D() > KINDA_SMALL_NUMBER);
PivotDirection2D =
UKismetMathLibrary::Normal(UKismetMathLibrary::VLerp(PivotDirection2D, UKismetMathLibrary::Normal(worldAcceleration2D), .5f));
UKismetMathLibrary::Normal(
UKismetMathLibrary::VLerp(PivotDirection2D, UKismetMathLibrary::Normal(worldAcceleration2D), .5f));
GetMovementDirectionThresholds(CardinalDirectionFromAcceleration, MovementDirectionThresholds);
CardinalDirectionFromAcceleration = (IsLookingOrAimingDirection()
? UOLSLocomotionBPLibrary::GetOppositeCardinalDirectional(
UOLSLocomotionBPLibrary::SelectCardinalDirectionFromAngle(
UKismetAnimationLibrary::CalculateDirection(PivotDirection2D, WorldRotation),
CardinalDirectionDeadZone, EOLSCardinalDirection::EForward))
: EOLSCardinalDirection::EBackward);
? UOLSLocomotionBPLibrary::GetOppositeMovementDirection(
UOLSLocomotionBPLibrary::SelectMovementDirectionFromAngle(
UKismetAnimationLibrary::CalculateDirection(
PivotDirection2D, WorldRotation),
RotationMode, Gait,
MovementDirectionBias,
MovementDirectionThresholds),
MovementDirectionBias)
: EOLSMovementDirection::EBackward);
if (HasAcceleration())
{
@ -498,10 +502,16 @@ bool UOLSBaseLayerAnimInstance::ShouldDistanceMatchStop() const
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);
const bool isPivotFwdOrBwd = (PivotInitialDirection == EOLSMovementDirection::EForward || PivotInitialDirection ==
EOLSMovementDirection::EBackward);
const bool isVelocityFwdOrBwd = (LocalVelocityDirection == EOLSMovementDirection::EForward || LocalVelocityDirection
== EOLSMovementDirection::EBackward);
const bool isPivotLeftOrRight = (PivotInitialDirection == EOLSMovementDirection::ELeftLeft || PivotInitialDirection
== EOLSMovementDirection::ELeftRight || PivotInitialDirection == EOLSMovementDirection::ERightLeft ||
PivotInitialDirection == EOLSMovementDirection::ERightRight);
const bool isVelocityLeftOrRight = (LocalVelocityDirection == EOLSMovementDirection::ELeftLeft ||
LocalVelocityDirection == EOLSMovementDirection::ELeftRight || LocalVelocityDirection ==
EOLSMovementDirection::ERightLeft || LocalVelocityDirection == EOLSMovementDirection::ERightRight);
return (isPivotFwdOrBwd && !isVelocityFwdOrBwd) || (isPivotLeftOrRight && !isVelocityLeftOrRight);
}
@ -611,3 +621,45 @@ UOLSLocomotionComponent* UOLSBaseLayerAnimInstance::ThreadSafeGetLocomotionCompo
{
return LocomotionComponent;
}
void UOLSBaseLayerAnimInstance::GetMovementDirectionThresholds(const EOLSMovementDirection& movementDirection, FOLSMovementDirectionThresholds& outMovementThresholds)
{
if (movementDirection == EOLSMovementDirection::EForward || movementDirection == EOLSMovementDirection::EBackward)
{
outMovementThresholds.FL = -60.f;
outMovementThresholds.FR = 60.f;
outMovementThresholds.BL = -120.f;
outMovementThresholds.BR = 120.f;
return;
}
if (movementDirection == EOLSMovementDirection::ELeftLeft || movementDirection ==
EOLSMovementDirection::ELeftRight || movementDirection == EOLSMovementDirection::ERightLeft ||
movementDirection == EOLSMovementDirection::ERightRight)
{
if (bIsPivoting)
{
outMovementThresholds.FL = -60.f;
outMovementThresholds.FR = 60.f;
outMovementThresholds.BL = -120.f;
outMovementThresholds.BR = 120.f;
}
else
{
if (bIsLooping && IsAimingDirection())
{
outMovementThresholds.FL = -60.f;
outMovementThresholds.FR = 60.f;
outMovementThresholds.BL = -140.f;
outMovementThresholds.BR = 140.f;
}
else
{
outMovementThresholds.FL = -40.f;
outMovementThresholds.FR = 40.f;
outMovementThresholds.BL = -120.f;
outMovementThresholds.BR = 120.f;
}
}
}
}

View File

@ -131,13 +131,12 @@ UAnimSequence* UOLSBaseLinkedLayerAnimInstance::SelectTurnInPlaceAnimation(
UAnimSequence* UOLSBaseLinkedLayerAnimInstance::SelectStartCycleAnimation(const bool isCrouching,
const bool isAiming,
const EOLSGait gait,
const EOLSCardinalDirection velocityDirection,
const EOLSHipDirection hipDirection,
const EOLSMovementDirection velocityDirection,
const float angle) const
{
if (isAiming)
{
return GetGaitAnimSets(isCrouching, gait).GaitAnimSet_CameraFacing.GetStartCycleFromHipDirection(hipDirection).
return GetGaitAnimSets(isCrouching, gait).GaitAnimSet_CameraFacing.StartCycle.
GetMovementAnimByCardinalDirection(
velocityDirection, FeetPositionData.IsRightFootIsFront());
}
@ -150,14 +149,12 @@ UAnimSequence* UOLSBaseLinkedLayerAnimInstance::SelectStartCycleAnimation(const
UAnimSequence* UOLSBaseLinkedLayerAnimInstance::SelectCycleAnimation(const bool isCrouching,
const bool isAiming,
const EOLSGait gait,
const EOLSCardinalDirection velocityDirection,
const EOLSHipDirection hipDirection) const
const EOLSMovementDirection velocityDirection) const
{
if (isAiming)
{
return GetGaitAnimSets(isCrouching, gait).GaitAnimSet_CameraFacing.GetCycleFromHipDirection(hipDirection).
GetMovementAnimByCardinalDirection(
velocityDirection, FeetPositionData.IsRightFootIsFront());
return GetGaitAnimSets(isCrouching, gait).GaitAnimSet_CameraFacing.Cycle.GetMovementAnimByCardinalDirection(
velocityDirection);
}
return GetGaitAnimSets(isCrouching, gait).GaitAnimSet_ForwardFacing.Cycle;
@ -166,14 +163,12 @@ UAnimSequence* UOLSBaseLinkedLayerAnimInstance::SelectCycleAnimation(const bool
UAnimSequence* UOLSBaseLinkedLayerAnimInstance::SelectPivotAnimation(const bool isCrouching,
const bool isAiming,
const EOLSGait gait,
const EOLSCardinalDirection velocityDirection,
const EOLSHipDirection hipDirection,
const EOLSMovementDirection velocityDirection,
const float angle) const
{
if (isAiming)
{
return GetGaitAnimSets(isCrouching, gait).GaitAnimSet_CameraFacing.GetPivotFromHipDirection(hipDirection).
GetMovementAnimByCardinalDirection(
return GetGaitAnimSets(isCrouching, gait).GaitAnimSet_CameraFacing.Pivot.GetMovementAnimByCardinalDirection(
velocityDirection, FeetPositionData.IsRightFootIsFront());
}
@ -184,13 +179,12 @@ UAnimSequence* UOLSBaseLinkedLayerAnimInstance::SelectPivotAnimation(const bool
UAnimSequence* UOLSBaseLinkedLayerAnimInstance::SelectStopCycleAnimation(const bool isCrouching,
const bool isAiming,
const EOLSGait gait,
const EOLSCardinalDirection velocityDirection,
const EOLSHipDirection hipDirection) const
const EOLSMovementDirection velocityDirection) const
{
if (isAiming)
{
return GetGaitAnimSets(isCrouching, gait).
GaitAnimSet_CameraFacing.GetStopCycleFromHipDirection(hipDirection).GetMovementAnimByCardinalDirection(
GaitAnimSet_CameraFacing.StopCycle.GetMovementAnimByCardinalDirection(
velocityDirection, FeetPositionData.IsRightFootIsFront());
}

View File

@ -92,22 +92,24 @@ UAnimSequence* FOLSMovementAnimSet_ForwardFacing_StartCycle::GetForward180LeftOr
}
class UAnimSequence* FOLSMovementAnimSet_ForwardFacing_StartCycle::GetMovementAnimationByAngle(
const EOLSCardinalDirection direction, const float angle, const bool isRightFootFarFromTarget) const
const EOLSMovementDirection direction, const float angle, const bool isRightFootFarFromTarget) const
{
TObjectPtr<UAnimSequence> result = nullptr;
switch (direction)
{
case EOLSCardinalDirection::EForward:
case EOLSMovementDirection::EForward:
result = GetForwardLeftOrRightFoot(isRightFootFarFromTarget);
break;
case EOLSCardinalDirection::ELeft:
case EOLSMovementDirection::ELeftLeft:
case EOLSMovementDirection::ELeftRight:
result = Forward90L;
break;
case EOLSCardinalDirection::ERight:
case EOLSMovementDirection::ERightLeft:
case EOLSMovementDirection::ERightRight:
result = Forward90R;
break;
case EOLSCardinalDirection::EBackward:
case EOLSMovementDirection::EBackward:
result = GetForward180LeftOrRightByAngle(angle);
break;
}
@ -128,6 +130,35 @@ UAnimSequence* FOLSMovementAnimSet_ForwardFacing_StopCycle::GetLeftOrRightAnim(c
return Stop.GetForwardLeftOrRightFoot(isRightFootPlanted);
}
class UAnimSequence* FOLSMovementAnimSet_CameraFacing_Directional_Cycle::GetMovementAnimByCardinalDirection(
const EOLSMovementDirection& direction) const
{
TObjectPtr<UAnimSequence> result = nullptr;
switch (direction)
{
case EOLSMovementDirection::EForward:
result = Forward;
break;
case EOLSMovementDirection::EBackward:
result = Backward;
break;
case EOLSMovementDirection::ELeftLeft:
result = LeftLeft;
break;
case EOLSMovementDirection::ELeftRight:
result = LeftRight;
break;
case EOLSMovementDirection::ERightRight:
result = RightRight;
break;
case EOLSMovementDirection::ERightLeft:
result = RightLeft;
break;
}
return result;
}
void FOLSGaitAnimSet::GetPlayRateByLocomotionState(const EOLSLocomotionStatePlayRate& state, FVector2D& outPlayRate) const
{
switch (state)
@ -144,27 +175,35 @@ void FOLSGaitAnimSet::GetPlayRateByLocomotionState(const EOLSLocomotionStatePlay
}
}
void FOLSMovementAnimSet_CameraFacing_Directional::GetMovementAnimSetByCardinalDirection(const EOLSCardinalDirection& direction,
void FOLSMovementAnimSet_CameraFacing_Directional::GetMovementAnimSetByCardinalDirection(
const EOLSMovementDirection& direction,
FOLSMovementAnimSet_FeetPosition& outAnimSet) const
{
switch (direction)
{
case EOLSCardinalDirection::EForward:
case EOLSMovementDirection::EForward:
outAnimSet = Forward;
break;
case EOLSCardinalDirection::EBackward:
case EOLSMovementDirection::EBackward:
outAnimSet = Backward;
break;
case EOLSCardinalDirection::ERight:
outAnimSet = Right;
case EOLSMovementDirection::ELeftLeft:
outAnimSet = LeftLeft;
break;
case EOLSCardinalDirection::ELeft:
outAnimSet = Left;
case EOLSMovementDirection::ELeftRight:
outAnimSet = LeftRight;
break;
case EOLSMovementDirection::ERightRight:
outAnimSet = RightRight;
break;
case EOLSMovementDirection::ERightLeft:
outAnimSet = RightLeft;
break;
}
}
UAnimSequence* FOLSMovementAnimSet_CameraFacing_Directional::GetMovementAnimByCardinalDirection(const EOLSCardinalDirection& direction,
UAnimSequence* FOLSMovementAnimSet_CameraFacing_Directional::GetMovementAnimByCardinalDirection(
const EOLSMovementDirection& direction,
const bool isRightFootFarFromTarget) const
{
FOLSMovementAnimSet_FeetPosition animSet;
@ -173,26 +212,6 @@ UAnimSequence* FOLSMovementAnimSet_CameraFacing_Directional::GetMovementAnimByCa
return animSet.GetForwardLeftOrRightFoot(isRightFootFarFromTarget);
}
const FOLSMovementAnimSet_CameraFacing_Directional& FOLSGaitAnimSet_CameraFacing::GetStartCycleFromHipDirection(const EOLSHipDirection hipDirection) const
{
return (hipDirection == EOLSHipDirection::EForward) ? StartCycle_HipForward : StartCycle_HipBackward;
}
const FOLSMovementAnimSet_CameraFacing_Directional& FOLSGaitAnimSet_CameraFacing::GetCycleFromHipDirection(const EOLSHipDirection hipDirection) const
{
return (hipDirection == EOLSHipDirection::EForward) ? Cycle_HipForward : Cycle_HipBackward;
}
const FOLSMovementAnimSet_CameraFacing_Directional& FOLSGaitAnimSet_CameraFacing::GetPivotFromHipDirection(const EOLSHipDirection hipDirection) const
{
return (hipDirection == EOLSHipDirection::EForward) ? Pivot_HipForward : Pivot_HipBackward;
}
const FOLSMovementAnimSet_CameraFacing_Directional& FOLSGaitAnimSet_CameraFacing::GetStopCycleFromHipDirection(const EOLSHipDirection hipDirection) const
{
return (hipDirection == EOLSHipDirection::EForward) ? StopCycle_HipForward : StopCycle_HipBackward;
}
UAnimSequence* FOLSStanceAnimSets::GetIdleAnimation() const
{
return IdleAndTurnInPlaceAnimSet.GetIdleAnimation();

View File

@ -5,60 +5,103 @@
DEFINE_LOG_CATEGORY_STATIC(LogOLSLocomotionLibrary, Verbose, All);
EOLSCardinalDirection UOLSLocomotionBPLibrary::SelectCardinalDirectionFromAngle(float angle,
float deadZone,
EOLSCardinalDirection currentDirection,
bool useCurrentDirection /* = false */)
EOLSMovementDirection UOLSLocomotionBPLibrary::SelectMovementDirectionFromAngle(float angle,
const EOLSRotationMode& rotationMode,
const EOLSGait& gait,
const EOLSMovementDirectionBias& movementDirectionBias,
const FOLSMovementDirectionThresholds& movementDirectionThreshold)
{
const float absAngle = FMath::Abs(angle);
float fwdDeadZone = deadZone;
float bwdDeadZone = deadZone;
if (useCurrentDirection)
EOLSMovementDirection result = EOLSMovementDirection::EForward;
if (rotationMode == EOLSRotationMode::EVelocityDirection || gait == EOLSGait::ESprint)
{
if (currentDirection == EOLSCardinalDirection::EForward)
{
fwdDeadZone *= 2.f;
}
else if (currentDirection == EOLSCardinalDirection::EBackward)
{
bwdDeadZone *= 2.f;
}
return result;
}
if(absAngle <= (45 + fwdDeadZone))
const bool isAngleForwardDirection = FMath::IsWithinInclusive(angle,
movementDirectionThreshold.FL,
movementDirectionThreshold.FR);
const bool isAngleLeftDirection = FMath::IsWithinInclusive(angle,
movementDirectionThreshold.BL,
movementDirectionThreshold.FL);
const bool isAngleRightDirection = FMath::IsWithinInclusive(angle,
movementDirectionThreshold.FR,
movementDirectionThreshold.BR);
if (isAngleForwardDirection)
{
return EOLSCardinalDirection::EForward;
result = EOLSMovementDirection::EForward;
}
else if (absAngle >= (135 - bwdDeadZone))
else if (isAngleLeftDirection)
{
return EOLSCardinalDirection::EBackward;
switch (movementDirectionBias)
{
case EOLSMovementDirectionBias::ELeftFoot_F:
result = EOLSMovementDirection::ELeftLeft;
break;
case EOLSMovementDirectionBias::ERightFoot_F:
result = EOLSMovementDirection::ELeftRight;
break;
}
else if (angle > 0)
}
else if (isAngleRightDirection)
{
return EOLSCardinalDirection::ERight;
switch (movementDirectionBias)
{
case EOLSMovementDirectionBias::ELeftFoot_F:
result = EOLSMovementDirection::ERightLeft;
break;
case EOLSMovementDirectionBias::ERightFoot_F:
result = EOLSMovementDirection::ERightRight;
break;
}
}
else
{
result = EOLSMovementDirection::EBackward;
}
return EOLSCardinalDirection::ELeft;
return result;
}
EOLSCardinalDirection UOLSLocomotionBPLibrary::GetOppositeCardinalDirectional(EOLSCardinalDirection currentDirection)
EOLSMovementDirection UOLSLocomotionBPLibrary::GetOppositeMovementDirection(
const EOLSMovementDirection& currentDirection,
const EOLSMovementDirectionBias& movementDirectionBias)
{
switch (currentDirection)
EOLSMovementDirection result = EOLSMovementDirection::EForward;
if (currentDirection == EOLSMovementDirection::EForward)
{
case EOLSCardinalDirection::EForward: {return EOLSCardinalDirection::EBackward;}
case EOLSCardinalDirection::EBackward: {return EOLSCardinalDirection::EForward;}
case EOLSCardinalDirection::ELeft: {return EOLSCardinalDirection::ERight;}
case EOLSCardinalDirection::ERight: {return EOLSCardinalDirection::ELeft;}
result = EOLSMovementDirection::EBackward;
}
else if (currentDirection == EOLSMovementDirection::ELeftLeft || currentDirection == EOLSMovementDirection::ELeftRight)
{
switch (movementDirectionBias)
{
case EOLSMovementDirectionBias::ELeftFoot_F:
result = EOLSMovementDirection::ERightLeft;
break;
case EOLSMovementDirectionBias::ERightFoot_F:
result = EOLSMovementDirection::ERightRight;
break;
}
}
else if (currentDirection == EOLSMovementDirection::ERightLeft || currentDirection == EOLSMovementDirection::ERightRight)
{
switch (movementDirectionBias)
{
case EOLSMovementDirectionBias::ELeftFoot_F:
result = EOLSMovementDirection::ELeftLeft;
break;
case EOLSMovementDirectionBias::ERightFoot_F:
result = EOLSMovementDirection::ELeftRight;
break;
}
}
else
{
result = EOLSMovementDirection::EBackward;
}
return EOLSCardinalDirection::EForward;
}
EOLSHipDirection UOLSLocomotionBPLibrary::GetOppositeHipDirection(EOLSHipDirection currentHipDirection)
{
return (currentHipDirection == EOLSHipDirection::EForward ? EOLSHipDirection::EBackward : EOLSHipDirection::EForward);
return result;
}
void UOLSLocomotionBPLibrary::TryLinkAnimLayer(USkeletalMeshComponent* mesh,

View File

@ -160,6 +160,11 @@ protected:
UFUNCTION(BlueprintCallable, Category = "Components", meta = (BlueprintThreadSafe))
class UOLSLocomotionComponent* ThreadSafeGetLocomotionComponent() const;
protected:
UFUNCTION(BlueprintCallable, Category = "Movement Direciton", meta = (BlueprintThreadSafe))
void GetMovementDirectionThresholds(const EOLSMovementDirection& movementDirection, FOLSMovementDirectionThresholds& outMovementThresholds);
protected:
UPROPERTY(BlueprintReadOnly, Category = "PawnInfo|LocationData")
@ -235,10 +240,10 @@ protected:
float LocalVelocityDirectionAngleWithOffset = 0.f;
UPROPERTY(BlueprintReadOnly, Category = "ThreadSafe|VelocityData")
EOLSCardinalDirection LocalVelocityDirection = EOLSCardinalDirection::EForward;
EOLSMovementDirection LocalVelocityDirection = EOLSMovementDirection::EForward;
UPROPERTY(BlueprintReadOnly, Category = "ThreadSafe|VelocityData")
EOLSCardinalDirection LocalVelocityDirectionNoOffset = EOLSCardinalDirection::EForward;
EOLSMovementDirection LocalVelocityDirectionNoOffset = EOLSMovementDirection::EForward;
UPROPERTY(BlueprintReadOnly, Category = "ThreadSafe|VelocityData")
uint8 bHasVelocity : 1;
@ -261,7 +266,7 @@ protected:
float LocalAccelerationDirection = 0.f;
UPROPERTY(BlueprintReadOnly, Category = "ThreadSafe|AccelerationData")
EOLSCardinalDirection CardinalDirectionFromAcceleration = EOLSCardinalDirection::EForward;
EOLSMovementDirection CardinalDirectionFromAcceleration = EOLSMovementDirection::EForward;
protected:
@ -345,23 +350,29 @@ protected:
protected:
UPROPERTY(BlueprintReadWrite, Category = "ThreadSafe|LocomotionSMData")
uint8 bIsPivoting : 1 = false;
UPROPERTY(BlueprintReadWrite, Category = "ThreadSafe|LocomotionSMData")
uint8 bIsLooping : 1 = false;
UPROPERTY(BlueprintReadWrite, Category = "ThreadSafe|LocomotionSMData")
float PivotInitialVelocityDirection = 0.f;
UPROPERTY(BlueprintReadWrite, Category = "ThreadSafe|LocomotionSMData")
EOLSCardinalDirection PivotInitialDirection = EOLSCardinalDirection::EForward;
EOLSMovementDirection PivotInitialDirection = EOLSMovementDirection::EForward;
UPROPERTY(BlueprintReadWrite, Category = "ThreadSafe|LocomotionSMData")
float LastPivotTime = 0.f;
UPROPERTY(BlueprintReadWrite, Category = "ThreadSafe|LocomotionSMData")
EOLSCardinalDirection StartDirection = EOLSCardinalDirection::EForward;
EOLSMovementDirection StartDirection = EOLSMovementDirection::EForward;
UPROPERTY(BlueprintReadWrite, Category = "ThreadSafe|LocomotionSMData")
EOLSGait StopInitialGait = EOLSGait::EWalk;
UPROPERTY(BlueprintReadWrite, Category = "ThreadSafe|LocomotionSMData")
EOLSCardinalDirection StopLocalVelocityCardinalDirection = EOLSCardinalDirection::EForward;
EOLSMovementDirection StopLocalVelocityDirection = EOLSMovementDirection::EForward;
UPROPERTY(BlueprintReadWrite, Category = "ThreadSafe|LocomotionSMData")
uint8 bHasGaitChanged : 1 = false;
@ -378,6 +389,9 @@ protected:
UPROPERTY(BlueprintReadWrite, Category = "ThreadSafe|LocomotionSMData")
EOLSRotationMode LastRotationMode = EOLSRotationMode::EVelocityDirection;
UPROPERTY(BlueprintReadWrite, Category = "ThreadSafe|LocomotionSMData")
FOLSMovementDirectionThresholds MovementDirectionThresholds;
UPROPERTY(BlueprintReadWrite, Category = "ThreadSafe|LocomotionSMData")
TObjectPtr<class UAnimInstance> LastLinkedLayer = nullptr;
@ -423,6 +437,9 @@ protected:
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Settings|VelocityData")
float CardinalDirectionDeadZone = 10.f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Settings|MovementDirection")
EOLSMovementDirectionBias MovementDirectionBias = EOLSMovementDirectionBias::ELeftFoot_F;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Settings|GameplayTagBindings")
FGameplayTag ADSGameplayTag = FGameplayTag::EmptyTag;

View File

@ -65,31 +65,27 @@ protected:
class UAnimSequence* SelectStartCycleAnimation(const bool isCrouching,
const bool isAiming,
const EOLSGait gait,
const EOLSCardinalDirection velocityDirection,
const EOLSHipDirection hipDirection,
const EOLSMovementDirection velocityDirection,
const float angle) const;
UFUNCTION(BlueprintCallable, meta = (BlueprintThreadSafe), Category = "ThreadSafe|Selectors")
class UAnimSequence* SelectCycleAnimation(const bool isCrouching,
const bool isAiming,
const EOLSGait gait,
const EOLSCardinalDirection velocityDirection,
const EOLSHipDirection hipDirection) const;
const EOLSMovementDirection velocityDirection) const;
UFUNCTION(BlueprintCallable, meta = (BlueprintThreadSafe), Category = "ThreadSafe|Selectors")
class UAnimSequence* SelectPivotAnimation(const bool isCrouching,
const bool isAiming,
const EOLSGait gait,
const EOLSCardinalDirection velocityDirection,
const EOLSHipDirection hipDirection,
const EOLSMovementDirection velocityDirection,
const float angle) const;
UFUNCTION(BlueprintCallable, meta = (BlueprintThreadSafe), Category = "ThreadSafe|Selectors")
class UAnimSequence* SelectStopCycleAnimation(const bool isCrouching,
const bool isAiming,
const EOLSGait gait,
const EOLSCardinalDirection velocityDirection,
const EOLSHipDirection hipDirection) const;
const EOLSMovementDirection velocityDirection) const;
UFUNCTION(BlueprintCallable, meta = (BlueprintThreadSafe), Category = "ThreadSafe|Selectors")
FVector2D SelectPlayRateByLocomotionState(const bool isCrouching, const bool isAiming, const EOLSGait gait,

View File

@ -9,6 +9,44 @@
#include "UObject/Object.h"
#include "OLSAnimationData.generated.h"
UENUM(BlueprintType)
enum class EOLSMovementDirection : uint8
{
EForward UMETA(DisplayName = "F"),
EBackward UMETA(DisplayName = "B"),
ELeftLeft UMETA(DisplayName = "LL"),
ELeftRight UMETA(DisplayName = "LR"),
ERightLeft UMETA(DisplayName = "RL"),
ERightRight UMETA(DisplayName = "RR")
};
UENUM(BlueprintType)
enum class EOLSMovementDirectionBias : uint8
{
ELeftFoot_F UMETA(DisplayName = "Left Foot Forward"),
ERightFoot_F UMETA(DisplayName = "Right Foot Forward"),
};
USTRUCT(BlueprintType)
struct FOLSMovementDirectionThresholds
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float FL = -60.f;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float FR = 60.f;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float BL = -120.f;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float BR = 120.f;
};
USTRUCT(BlueprintType)
struct FOLSFeetPositionSettings
{
@ -150,7 +188,7 @@ public:
class UAnimSequence* GetForwardLeftOrRightFoot(const bool isRightFootFarFromTarget) const;
class UAnimSequence* GetForward180LeftOrRightByAngle(const float angle) const;
class UAnimSequence* GetMovementAnimationByAngle(const EOLSCardinalDirection direction,
class UAnimSequence* GetMovementAnimationByAngle(const EOLSMovementDirection direction,
const float angle,
const bool isRightFootFarFromTarget) const;
@ -207,6 +245,36 @@ public:
};
#pragma endregion
USTRUCT(BlueprintType)
struct FOLSMovementAnimSet_CameraFacing_Directional_Cycle
{
GENERATED_BODY()
public:
class UAnimSequence* GetMovementAnimByCardinalDirection(const EOLSMovementDirection& direction) const;
public:
UPROPERTY(EditAnywhere, BlueprintReadOnly, meta = (DisplayName = "F"))
TObjectPtr<class UAnimSequence> Forward;
UPROPERTY(EditAnywhere, BlueprintReadOnly, meta = (DisplayName = "B"))
TObjectPtr<class UAnimSequence> Backward;
UPROPERTY(EditAnywhere, BlueprintReadOnly, meta = (DisplayName = "LL"))
TObjectPtr<class UAnimSequence> LeftLeft;
UPROPERTY(EditAnywhere, BlueprintReadOnly, meta = (DisplayName = "LR"))
TObjectPtr<class UAnimSequence> LeftRight;
UPROPERTY(EditAnywhere, BlueprintReadOnly, meta = (DisplayName = "RL"))
TObjectPtr<class UAnimSequence> RightLeft;
UPROPERTY(EditAnywhere, BlueprintReadOnly, meta = (DisplayName = "RR"))
TObjectPtr<class UAnimSequence> RightRight;
};
USTRUCT(BlueprintType)
struct FOLSMovementAnimSet_CameraFacing_Directional
{
@ -214,25 +282,31 @@ struct FOLSMovementAnimSet_CameraFacing_Directional
protected:
void GetMovementAnimSetByCardinalDirection(const EOLSCardinalDirection& direction, FOLSMovementAnimSet_FeetPosition& outAnimSet) const;
void GetMovementAnimSetByCardinalDirection(const EOLSMovementDirection& direction, FOLSMovementAnimSet_FeetPosition& outAnimSet) const;
public:
class UAnimSequence* GetMovementAnimByCardinalDirection(const EOLSCardinalDirection& direction, const bool isRightFootFarFromTarget) const;
class UAnimSequence* GetMovementAnimByCardinalDirection(const EOLSMovementDirection& direction, const bool isRightFootFarFromTarget) const;
public:
UPROPERTY(EditAnywhere, BlueprintReadOnly)
UPROPERTY(EditAnywhere, BlueprintReadOnly, meta = (DisplayName = "F"))
FOLSMovementAnimSet_FeetPosition Forward;
UPROPERTY(EditAnywhere, BlueprintReadOnly)
UPROPERTY(EditAnywhere, BlueprintReadOnly, meta = (DisplayName = "B"))
FOLSMovementAnimSet_FeetPosition Backward;
UPROPERTY(EditAnywhere, BlueprintReadOnly)
FOLSMovementAnimSet_FeetPosition Right;
UPROPERTY(EditAnywhere, BlueprintReadOnly, meta = (DisplayName = "LL"))
FOLSMovementAnimSet_FeetPosition LeftLeft;
UPROPERTY(EditAnywhere, BlueprintReadOnly)
FOLSMovementAnimSet_FeetPosition Left;
UPROPERTY(EditAnywhere, BlueprintReadOnly, meta = (DisplayName = "LR"))
FOLSMovementAnimSet_FeetPosition LeftRight;
UPROPERTY(EditAnywhere, BlueprintReadOnly, meta = (DisplayName = "RL"))
FOLSMovementAnimSet_FeetPosition RightLeft;
UPROPERTY(EditAnywhere, BlueprintReadOnly, meta = (DisplayName = "RR"))
FOLSMovementAnimSet_FeetPosition RightRight;
};
USTRUCT(BlueprintType)
@ -294,36 +368,17 @@ struct FOLSGaitAnimSet_CameraFacing : public FOLSGaitAnimSet
public:
const FOLSMovementAnimSet_CameraFacing_Directional& GetStartCycleFromHipDirection(const EOLSHipDirection hipDirection) const;
const FOLSMovementAnimSet_CameraFacing_Directional& GetCycleFromHipDirection(const EOLSHipDirection hipDirection) const;
const FOLSMovementAnimSet_CameraFacing_Directional& GetPivotFromHipDirection(const EOLSHipDirection hipDirection) const;
const FOLSMovementAnimSet_CameraFacing_Directional& GetStopCycleFromHipDirection(const EOLSHipDirection hipDirection) const;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Gait Anim Set")
FOLSMovementAnimSet_CameraFacing_Directional StartCycle;
public:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Gait Anim Set")
FOLSMovementAnimSet_CameraFacing_Directional_Cycle Cycle;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Gait Anim Set | Hip Forward")
FOLSMovementAnimSet_CameraFacing_Directional StartCycle_HipForward;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Gait Anim Set")
FOLSMovementAnimSet_CameraFacing_Directional Pivot;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Gait Anim Set | Hip Forward")
FOLSMovementAnimSet_CameraFacing_Directional Cycle_HipForward;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Gait Anim Set | Hip Forward")
FOLSMovementAnimSet_CameraFacing_Directional Pivot_HipForward;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Gait Anim Set | Hip Forward")
FOLSMovementAnimSet_CameraFacing_Directional StopCycle_HipForward;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Gait Anim Set | Hip Backward")
FOLSMovementAnimSet_CameraFacing_Directional StartCycle_HipBackward;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Gait Anim Set | Hip Backward")
FOLSMovementAnimSet_CameraFacing_Directional Cycle_HipBackward;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Gait Anim Set | Hip Backward")
FOLSMovementAnimSet_CameraFacing_Directional Pivot_HipBackward;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Gait Anim Set | Hip Backward")
FOLSMovementAnimSet_CameraFacing_Directional StopCycle_HipBackward;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Gait Anim Set")
FOLSMovementAnimSet_CameraFacing_Directional StopCycle;
};
USTRUCT(BlueprintType)
@ -379,9 +434,6 @@ public:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Stance Anim Sets")
FOLSGaitAnimSets WalkAnimSets;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Stance Anim Sets")
uint8 bUseFeetPosition : 1 = false;
};
USTRUCT(BlueprintType)

View File

@ -25,15 +25,6 @@ enum class EOLSHipDirection : uint8
EBackward UMETA(DisplayName = "Backward")
};
UENUM(BlueprintType)
enum class EOLSCardinalDirection : uint8
{
EForward UMETA(DisplayName = "Forward"),
EBackward UMETA(DisplayName = "Backward"),
ELeft UMETA(DisplayName = "Left"),
ERight UMETA(DisplayName = "Right")
};
UENUM(BlueprintType)
enum class EOLSLocomotionStatePlayRate : uint8
{

View File

@ -20,13 +20,14 @@ class OLSANIMATION_API UOLSLocomotionBPLibrary : public UBlueprintFunctionLibrar
public:
UFUNCTION(BlueprintCallable,BlueprintPure,Category = "OLS|Function Library",meta=(BlueprintThreadSafe))
static EOLSCardinalDirection SelectCardinalDirectionFromAngle(float angle, float deadZone, EOLSCardinalDirection currentDirection, bool useCurrentDirection = false);
static EOLSMovementDirection SelectMovementDirectionFromAngle(float angle,
const EOLSRotationMode& rotationMode,
const EOLSGait& gait,
const EOLSMovementDirectionBias& movementDirectionBias,
const FOLSMovementDirectionThresholds& movementDirectionThreshold);
UFUNCTION(BlueprintCallable,BlueprintPure,Category = "OLS|Function Library",meta=(BlueprintThreadSafe))
static EOLSCardinalDirection GetOppositeCardinalDirectional(EOLSCardinalDirection currentDirection);
UFUNCTION(BlueprintCallable,BlueprintPure,Category = "OLS|Function Library",meta=(BlueprintThreadSafe))
static EOLSHipDirection GetOppositeHipDirection(EOLSHipDirection currentHipDirection);
static EOLSMovementDirection GetOppositeMovementDirection(const EOLSMovementDirection& currentDirection, const EOLSMovementDirectionBias& movementDirectionBias);
public: