Implemented Stop by foot planted and pivot feet curve or foot flags selection

This commit is contained in:
mrlee207 2025-05-14 12:38:48 +07:00
parent d4a5051eb2
commit 49ab3fd41f
14 changed files with 169 additions and 74 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 51 KiB

File diff suppressed because one or more lines are too long

View File

@ -58,9 +58,9 @@ void UOLSBaseLinkedLayerAnimInstance::NativeThreadSafeUpdateSkeletonControlData(
{
OrientationWarpingAlpha = GetCurveValue(EnableOrientationWarpingName);
const float feetPositionValue = GetCurveValue(FeetPositionCurveName);
bIsRightFootPlanted = feetPositionValue > 0.5f;
bIsLeftFootPlanted = FMath::Abs(feetPositionValue) > 0.5f;
FeetPositionCurve = GetCurveValue(FeetPositionCurveName);
bIsRightFootPlanted = FeetPositionCurve > FootPlantedThreshold;
bIsLeftFootPlanted = FMath::Abs(FeetPositionCurve) > FootPlantedThreshold;
// If neither foot is planted, use the last valid foot
if (!bIsRightFootPlanted && !bIsLeftFootPlanted)
@ -78,6 +78,7 @@ void UOLSBaseLinkedLayerAnimInstance::NativeThreadSafeUpdateSkeletonControlData(
{
// Update the last valid foot
bWasRightFootPlantingChanged = bIsRightFootPlanted;
bWasLeftFootPlantingChanged = bIsLeftFootPlanted;
}
}
@ -190,8 +191,11 @@ UAnimSequence* UOLSBaseLinkedLayerAnimInstance::SelectPivotAnimation(const bool
GetMovementAnimationByCardinalDirection(velocityDirection);
}
return GetGaitAnimSets(isCrouching, gait).GaitAnimSet_ForwardFacing.Pivot.GetLeftOrRightByAngle(
angle, bIsLeftFootPlanted, bIsRightFootPlanted, outPivotTime);
return (bUseFeetFlagsForPivot)
? GetGaitAnimSets(isCrouching, gait).GaitAnimSet_ForwardFacing.Pivot.GetLeftOrRightAnim(
angle, bIsLeftFootPlanted, bIsRightFootPlanted, outPivotTime)
: GetGaitAnimSets(isCrouching, gait).GaitAnimSet_ForwardFacing.Pivot.GetLeftOrRightAnim(
angle, FeetPositionCurve, outPivotTime);
}
UAnimSequence* UOLSBaseLinkedLayerAnimInstance::SelectStopCycleAnimation(const bool isCrouching,
@ -207,7 +211,7 @@ UAnimSequence* UOLSBaseLinkedLayerAnimInstance::SelectStopCycleAnimation(const b
GetMovementAnimationByCardinalDirection(velocityDirection);
}
return GetGaitAnimSets(isCrouching, gait).GaitAnimSet_ForwardFacing.StopCycle;
return GetGaitAnimSets(isCrouching, gait).GaitAnimSet_ForwardFacing.Stop.GetLeftOrRightStopAnim(FeetPositionCurve);
}
FVector2D UOLSBaseLinkedLayerAnimInstance::SelectPlayRateByLocomotionState(

View File

@ -117,8 +117,19 @@ class UAnimSequence* FOLSMovementAnimSet_ForwardFacing_StartCycle::GetMovementAn
return result;
}
class UAnimSequence* FOLSMovementAnimSet_ForwardFacing_Stop::GetLeftOrRightStopAnim(const float feetPosition) const
{
return (feetPosition > 0.f ? StopR : StopL);
}
void FOLSMovementAnimSets_ForwardFacing_Pivot::GetLeftOrRightAnimSet(float feetPosition,
FOLSMovementAnimSet_ForwardFacing_Pivot& outAnimSet) const
{
outAnimSet = (feetPosition > 0.f) ? Pivot_RightFoot : Pivot_LeftFoot;
}
void FOLSMovementAnimSets_ForwardFacing_Pivot::GetLeftOrRightAnimSet(const bool isLeftFootPlanted,
const bool isRightFootPlanted, FOLSMovementAnimSet_ForwardFacing_Pivot& outAnimSet) const
const bool isRightFootPlanted, FOLSMovementAnimSet_ForwardFacing_Pivot& outAnimSet) const
{
if (isLeftFootPlanted)
{
@ -130,8 +141,8 @@ void FOLSMovementAnimSets_ForwardFacing_Pivot::GetLeftOrRightAnimSet(const bool
}
}
class UAnimSequence* FOLSMovementAnimSets_ForwardFacing_Pivot::GetLeftOrRightByAngle(const float angle,
const bool isLeftFootPlanted, const bool isRightFootPlanted, float& outPivotTime) const
class UAnimSequence* FOLSMovementAnimSets_ForwardFacing_Pivot::GetLeftOrRightAnim(const float angle,
const bool isLeftFootPlanted, const bool isRightFootPlanted, float& outPivotTime) const
{
FOLSMovementAnimSet_ForwardFacing_Pivot animSet;
GetLeftOrRightAnimSet(isLeftFootPlanted, isRightFootPlanted, animSet);
@ -141,6 +152,17 @@ class UAnimSequence* FOLSMovementAnimSets_ForwardFacing_Pivot::GetLeftOrRightByA
return (angle > 0.f) ? animSet.Pivot180R : animSet.Pivot180L;
}
class UAnimSequence* FOLSMovementAnimSets_ForwardFacing_Pivot::GetLeftOrRightAnim(const float angle,
const float feetPosition, float& outPivotTime) const
{
FOLSMovementAnimSet_ForwardFacing_Pivot animSet;
GetLeftOrRightAnimSet(feetPosition, animSet);
outPivotTime = PivotTime;
return (angle > 0.f) ? animSet.Pivot180R : animSet.Pivot180L;
}
void FOLSGaitAnimSet::GetPlayRateByLocomotionState(const EOLSLocomotionStatePlayRate& state, FVector2D& outPlayRate) const
{
switch (state)

View File

@ -206,9 +206,15 @@ protected:
protected:
UPROPERTY(BlueprintReadWrite, Category = "ThreadSafe|SkeletonControl|FeetPosition")
float FeetPositionCurve = 0.0f;
UPROPERTY(BlueprintReadWrite, Category = "ThreadSafe|SkeletonControl|FeetPosition")
uint8 bWasRightFootPlantingChanged : 1 = false;
UPROPERTY(BlueprintReadWrite, Category = "ThreadSafe|SkeletonControl|FeetPosition")
uint8 bWasLeftFootPlantingChanged : 1 = false;
UPROPERTY(BlueprintReadWrite, Category = "ThreadSafe|SkeletonControl|FeetPosition")
uint8 bIsRightFootPlanted : 1 = true;
@ -272,6 +278,35 @@ protected:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Settings|AnimSet|FeetPosition")
FName FeetPositionCurveName = NAME_None;
/**
* Threshold value to determine if a foot is considered planted on the ground.
* Range: 0.0 to 1.0, where:
* - Values closer to 0 make foot planting detection more sensitive
* - Values closer to 1 require more definitive foot contact
* Default value of 0.4 provides a balanced detection for most animations
*/
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Settings|AnimSet|FeetPosition",
meta = (ClampMin = "0.0", ClampMax = "1.0", UIMin = "0.0", UIMax = "1.0"))
float FootPlantedThreshold = 0.4f;
/**
* Determines the method used for selecting pivot animations based on foot positioning.
*
* When true:
* - Uses explicit foot planting flags (isLeftFootPlanted, isRightFootPlanted)
* - More precise control over pivot selection
* - Better for complex animation transitions
*
* When false:
* - Uses simplified feet position value
* - Relies on animation curves for foot position
* - More suitable for basic movement patterns
*
* @note This affects how pivot animations are chosen in FOLSMovementAnimSets_ForwardFacing_Pivot
* @see FOLSMovementAnimSets_ForwardFacing_Pivot::GetLeftOrRightAnim
*/
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Settings|AnimSet|FeetPosition")
uint8 bUseFeetFlagsForPivot : 1 = true;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Settings|StrideWarping")
float StrideWarpingBlendInDurationScaled = .2f;

View File

@ -181,10 +181,29 @@ public:
};
USTRUCT(BlueprintType)
struct FOLSMovementAnimSet_ForwardFacing_Pivot
struct FOLSMovementAnimSet_ForwardFacing_Stop
{
GENERATED_BODY()
public:
class UAnimSequence* GetLeftOrRightStopAnim(const float feetPosition) const;
public:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Movement Stop Anim Set")
TObjectPtr<class UAnimSequence> StopL = nullptr;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Movement Stop Anim Set")
TObjectPtr<class UAnimSequence> StopR = nullptr;
};
USTRUCT(BlueprintType)
struct FOLSMovementAnimSet_ForwardFacing_Pivot
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Movement Pivot Anim Set")
@ -202,15 +221,23 @@ struct FOLSMovementAnimSets_ForwardFacing_Pivot
protected:
void GetLeftOrRightAnimSet(const bool isLeftFootPlanted, const bool isRightFootPlanted,
void GetLeftOrRightAnimSet(const bool isLeftFootPlanted,
const bool isRightFootPlanted,
FOLSMovementAnimSet_ForwardFacing_Pivot& outAnimSet) const;
void GetLeftOrRightAnimSet(float feetPosition,
FOLSMovementAnimSet_ForwardFacing_Pivot& outAnimSet) const;
public:
class UAnimSequence* GetLeftOrRightByAngle(const float angle,
class UAnimSequence* GetLeftOrRightAnim(const float angle,
const bool isLeftFootPlanted,
const bool isRightFootPlanted,
float& outPivotTime) const;
class UAnimSequence* GetLeftOrRightAnim(const float angle,
const float feetPosition,
float& outPivotTime) const;
public:
@ -243,15 +270,14 @@ public:
void GetPlayRateByLocomotionState(const EOLSLocomotionStatePlayRate& state, FVector2D& outPlayRate) const;
public:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Stance Anim Sets")
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Gait Anim Sets")
FVector2D PlayRate_Start = FVector2D::ZeroVector;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Stance Anim Sets")
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Gait Anim Sets")
FVector2D PlayRate_Pivot = FVector2D::ZeroVector;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Stance Anim Sets")
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Gait Anim Sets")
FVector2D PlayRate_Cycle = FVector2D::ZeroVector;
};
@ -272,7 +298,7 @@ public:
FOLSMovementAnimSets_ForwardFacing_Pivot Pivot;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Gait Anim Set")
TObjectPtr<class UAnimSequence> StopCycle = nullptr;
FOLSMovementAnimSet_ForwardFacing_Stop Stop;
};
USTRUCT(BlueprintType)