diff --git a/Content/Characters/UEFN_Mannequin/AnimationLayers/ABP_UEFN_Base_New.uasset b/Content/Characters/UEFN_Mannequin/AnimationLayers/ABP_UEFN_Base_New.uasset index e281761..4cbaf5f 100644 Binary files a/Content/Characters/UEFN_Mannequin/AnimationLayers/ABP_UEFN_Base_New.uasset and b/Content/Characters/UEFN_Mannequin/AnimationLayers/ABP_UEFN_Base_New.uasset differ diff --git a/Content/Characters/UEFN_Mannequin/AnimationLayers/ABP_UEFN_FullBody_Base_New.uasset b/Content/Characters/UEFN_Mannequin/AnimationLayers/ABP_UEFN_FullBody_Base_New.uasset index 8e490a7..545c5b4 100644 Binary files a/Content/Characters/UEFN_Mannequin/AnimationLayers/ABP_UEFN_FullBody_Base_New.uasset and b/Content/Characters/UEFN_Mannequin/AnimationLayers/ABP_UEFN_FullBody_Base_New.uasset differ diff --git a/Plugins/Developer/RiderLink/Intermediate/FileSystemMappings.ini b/Plugins/Developer/RiderLink/Intermediate/FileSystemMappings.ini index 59ca7cc..25f3628 100644 --- a/Plugins/Developer/RiderLink/Intermediate/FileSystemMappings.ini +++ b/Plugins/Developer/RiderLink/Intermediate/FileSystemMappings.ini @@ -1,13 +1,13 @@ /Engine=C:/Program Files/Epic Games/UE_5.5/Engine/Shaders /ShaderAutogen=H:/Projects/OLS/Intermediate/ShaderAutogen -/Plugin/ComputeFramework=C:/Program Files/Epic Games/UE_5.5/Engine/Plugins/Runtime/ComputeFramework/Shaders -/Plugin/Runtime/HairStrands=C:/Program Files/Epic Games/UE_5.5/Engine/Plugins/Runtime/HairStrands/Shaders /Plugin/FX/Niagara=C:/Program Files/Epic Games/UE_5.5/Engine/Plugins/FX/Niagara/Shaders +/NNEDenoiserShaders=C:/Program Files/Epic Games/UE_5.5/Engine/Plugins/NNE/NNEDenoiser/Shaders /Plugin/GLTFExporter=C:/Program Files/Epic Games/UE_5.5/Engine/Plugins/Enterprise/GLTFExporter/Shaders /NFORDenoise=C:/Program Files/Epic Games/UE_5.5/Engine/Plugins/Experimental/NFORDenoise/Shaders /Plugin/ExrReaderShaders=C:/Program Files/Epic Games/UE_5.5/Engine/Plugins/Media/ImgMedia/Shaders /Plugin/WmfMedia=C:/Program Files/Epic Games/UE_5.5/Engine/Plugins/Media/WmfMedia/Shaders -/NNEDenoiserShaders=C:/Program Files/Epic Games/UE_5.5/Engine/Plugins/NNE/NNEDenoiser/Shaders +/Plugin/ComputeFramework=C:/Program Files/Epic Games/UE_5.5/Engine/Plugins/Runtime/ComputeFramework/Shaders +/Plugin/Runtime/HairStrands=C:/Program Files/Epic Games/UE_5.5/Engine/Plugins/Runtime/HairStrands/Shaders /Plugin/HoldoutComposite=C:/Program Files/Epic Games/UE_5.5/Engine/Plugins/Experimental/Compositing/HoldoutComposite/Shaders /Plugin/Optimus=C:/Program Files/Epic Games/UE_5.5/Engine/Plugins/Animation/DeformerGraph/Shaders /Plugin/Experimental/ChaosNiagara=C:/Program Files/Epic Games/UE_5.5/Engine/Plugins/Experimental/ChaosNiagara/Shaders diff --git a/Saved/AutoScreenshot.png b/Saved/AutoScreenshot.png index 74b63c7..9ded8b1 100644 Binary files a/Saved/AutoScreenshot.png and b/Saved/AutoScreenshot.png differ diff --git a/Saved/Autosaves/Game/Characters/UEFN_Mannequin/AnimationLayers/ABP_UEFN_Base_New_Auto1.uasset b/Saved/Autosaves/Game/Characters/UEFN_Mannequin/AnimationLayers/ABP_UEFN_Base_New_Auto1.uasset index 744d2ce..1e3693f 100644 Binary files a/Saved/Autosaves/Game/Characters/UEFN_Mannequin/AnimationLayers/ABP_UEFN_Base_New_Auto1.uasset and b/Saved/Autosaves/Game/Characters/UEFN_Mannequin/AnimationLayers/ABP_UEFN_Base_New_Auto1.uasset differ diff --git a/Saved/Autosaves/Game/Characters/UEFN_Mannequin/AnimationLayers/ABP_UEFN_FullBody_Base_New_Auto1.uasset b/Saved/Autosaves/Game/Characters/UEFN_Mannequin/AnimationLayers/ABP_UEFN_FullBody_Base_New_Auto1.uasset index 3bed8f5..e7e7106 100644 Binary files a/Saved/Autosaves/Game/Characters/UEFN_Mannequin/AnimationLayers/ABP_UEFN_FullBody_Base_New_Auto1.uasset and b/Saved/Autosaves/Game/Characters/UEFN_Mannequin/AnimationLayers/ABP_UEFN_FullBody_Base_New_Auto1.uasset differ diff --git a/Source/OLSAnimation/Private/AnimInstances/OLSBaseLayerAnimInstance.cpp b/Source/OLSAnimation/Private/AnimInstances/OLSBaseLayerAnimInstance.cpp index 6ff86d1..f734fa2 100644 --- a/Source/OLSAnimation/Private/AnimInstances/OLSBaseLayerAnimInstance.cpp +++ b/Source/OLSAnimation/Private/AnimInstances/OLSBaseLayerAnimInstance.cpp @@ -71,6 +71,7 @@ void UOLSBaseLayerAnimInstance::NativeBeginPlay() if (LocomotionComponent) { DesiredGait = LocomotionComponent->GetDesiredGait(); + DesiredMaxSpeed = LocomotionComponent->GetMaxSpeedByGait(DesiredGait); } }); @@ -82,6 +83,8 @@ void UOLSBaseLayerAnimInstance::NativeBeginPlay() PrevGait = prevGait; Gait = LocomotionComponent->GetGait(); bHasGaitChanged = true; + + DesiredMaxSpeed = LocomotionComponent->GetMaxSpeedByGait(Gait); } }); @@ -172,6 +175,10 @@ void UOLSBaseLayerAnimInstance::NativeUpdateVelocityData(const TScriptInterface< void UOLSBaseLayerAnimInstance::NativeUpdateAccelerationData(APawn* owningPawn, const float deltaSeconds) { OwningPawnAcceleration = MoveableInterface->GetCurrentAcceleration(); + + InputAmount = FMath::GetMappedRangeValueClamped(FVector2D(0.f, MoveableInterface->GetMaxAcceleration()), + FVector2D(0.f, 1.f), + MoveableInterface->GetCurrentAcceleration().Size()); } void UOLSBaseLayerAnimInstance::NativeUpdateCharacterStateData( @@ -293,7 +300,9 @@ void UOLSBaseLayerAnimInstance::NativeThreadSafeUpdateAccelerationData(const flo OwningPawnAcceleration.GetSafeNormal2D(), WorldRotation); } - if (LocalAcceleration2D.GetSafeNormal2D().Dot(LocalVelocity2D.GetSafeNormal2D()) < -.2f && HasAcceleration() && !bIsPivoting) + const float desiredMaxSpeed = DesiredMaxSpeed * InputAmount; + if (LocalAcceleration2D.GetSafeNormal2D().Dot(LocalVelocity2D.GetSafeNormal2D()) < -.2f && WorldVelocity.Size2D() > + desiredMaxSpeed * 0.5f && HasAcceleration() && !bIsPivoting) { bIsPivoting = true; } @@ -353,6 +362,9 @@ void UOLSBaseLayerAnimInstance::NativeThreadSafeUpdateCharacterStateData(const f TimeSinceFiredWeapon = (bGameplayTag_IsFiring) ? 0.f : TimeSinceFiredWeapon + deltaSeconds; } + const bool wasPivotingLastUpdate = bWasPivoting; + bWasPivoting = (bIsPivoting != wasPivotingLastUpdate); + // In air state. { bIsJumping = false; diff --git a/Source/OLSAnimation/Private/Components/OLSLocomotionComponent.cpp b/Source/OLSAnimation/Private/Components/OLSLocomotionComponent.cpp index 99ea8b8..7ef7811 100644 --- a/Source/OLSAnimation/Private/Components/OLSLocomotionComponent.cpp +++ b/Source/OLSAnimation/Private/Components/OLSLocomotionComponent.cpp @@ -202,6 +202,16 @@ void UOLSLocomotionComponent::SetRotationMode(EOLSRotationMode newRotationMode, } } +float UOLSLocomotionComponent::GetMaxSpeedByGait(const EOLSGait gait) const +{ + return Gaits.FindChecked(gait); +} + +const float& UOLSLocomotionComponent::GetMovementInputAmount() const +{ + return MovementInputAmount; +} + void UOLSLocomotionComponent::SetDesiredGait(const EOLSGait newGait, const bool shouldForce /* = false */) { if (shouldForce || DesiredGait != newGait) diff --git a/Source/OLSAnimation/Private/Libraries/OLSLocomotionBPLibrary.cpp b/Source/OLSAnimation/Private/Libraries/OLSLocomotionBPLibrary.cpp index 1ad2519..63807b9 100644 --- a/Source/OLSAnimation/Private/Libraries/OLSLocomotionBPLibrary.cpp +++ b/Source/OLSAnimation/Private/Libraries/OLSLocomotionBPLibrary.cpp @@ -481,6 +481,22 @@ FVector UOLSLocomotionBPLibrary::PredictGroundMovementPivotLocation(const FVecto return predictedPivotLocation; } +// +// float UOLSLocomotionBPLibrary::RotationMatching(const float deltaTime, const float interpSpeed, +// const float animRotAlpha, const FVector& acceleration, +// const float targetAngle, +// FOLSRotationMatchingData& outRotationMatchingData, +// float& outTargetRotationYaw) +// { +// const float animDesiredRotation = FRotator::NormalizeAxis(targetAngle * animRotAlpha); +// const float currentAccelDir = acceleration.GetSafeNormal2D().Rotation().Yaw; +// +// outRotationMatchingData.CurrentAccelDir = FRotator::NormalizeAxis() +// const float desiredRotationChange = FRotator::NormalizeAxis(FMath::RInterpTo( +// FRotator{0.0f, 0.f, 0.0f}, +// FRotator{0.0f, AnimDesiredRotation, 0.0f}, +// DeltaTime, InterpSpeed).Yaw); +// } EOLSCardinalDirection UOLSLocomotionBPLibrary::SelectCardinalDirectionFromAngle(float angle, float deadZone, diff --git a/Source/OLSAnimation/Public/AnimInstances/OLSBaseLayerAnimInstance.h b/Source/OLSAnimation/Public/AnimInstances/OLSBaseLayerAnimInstance.h index 798253e..e31e39b 100644 --- a/Source/OLSAnimation/Public/AnimInstances/OLSBaseLayerAnimInstance.h +++ b/Source/OLSAnimation/Public/AnimInstances/OLSBaseLayerAnimInstance.h @@ -254,6 +254,9 @@ protected: UPROPERTY(BlueprintReadOnly, Category = "ThreadSafe|AccelerationData") uint8 bIsPivoting : 1; + UPROPERTY(BlueprintReadOnly, Category = "ThreadSafe|AccelerationData") + uint8 bWasPivoting : 1; + UPROPERTY(BlueprintReadOnly, Category = "ThreadSafe|AccelerationData") FVector PivotDirection2D = FVector::ZeroVector; @@ -382,6 +385,12 @@ protected: TObjectPtr LastLinkedLayer = nullptr; protected: + + UPROPERTY(BlueprintReadWrite, Category = "ThreadSafe|LocomotionComponentData") + float DesiredMaxSpeed = 0.f; + + UPROPERTY(BlueprintReadWrite, Category = "ThreadSafe|LocomotionComponentData") + float InputAmount = 0.f; UPROPERTY(BlueprintReadWrite, Category = "ThreadSafe|LocomotionComponentData") EOLSGait DesiredGait = EOLSGait::EWalk; diff --git a/Source/OLSAnimation/Public/Components/OLSLocomotionComponent.h b/Source/OLSAnimation/Public/Components/OLSLocomotionComponent.h index 75cf913..4415b5b 100644 --- a/Source/OLSAnimation/Public/Components/OLSLocomotionComponent.h +++ b/Source/OLSAnimation/Public/Components/OLSLocomotionComponent.h @@ -66,6 +66,12 @@ public: UFUNCTION(BlueprintCallable, Category = "OLSLocomotionComponent") void SetRotationMode(EOLSRotationMode newRotationMode, bool shouldForce = false); + UFUNCTION(BlueprintCallable, Category = "OLSLocomotionComponent") + float GetMaxSpeedByGait(const EOLSGait gait) const; + + UFUNCTION(BlueprintCallable, Category = "OLSLocomotionComponent") + const float& GetMovementInputAmount() const; + public: UFUNCTION(BlueprintCallable, Category = "OLSLocomotionComponent") diff --git a/Source/OLSAnimation/Public/Data/OLSAnimationData.h b/Source/OLSAnimation/Public/Data/OLSAnimationData.h index 276f784..ea9f626 100644 --- a/Source/OLSAnimation/Public/Data/OLSAnimationData.h +++ b/Source/OLSAnimation/Public/Data/OLSAnimationData.h @@ -9,6 +9,32 @@ #include "UObject/Object.h" #include "OLSAnimationData.generated.h" +USTRUCT(BlueprintType) +struct FOLSRotationMatchingData +{ + GENERATED_BODY() + +public: + + UPROPERTY(BlueprintReadWrite, Category = "RotationMatchingData") + float TargetAngle = 0.0f; + + UPROPERTY(BlueprintReadWrite, Category = "RotationMatchingData") + float CurrentAccelDir = 0.0f; + + UPROPERTY(BlueprintReadWrite, Category = "RotationMatchingData") + float EntryAccelDir = 0.0f; + + UPROPERTY(BlueprintReadWrite, Category = "RotationMatchingData") + float EntryRotYaw = 0.0f; + + UPROPERTY(BlueprintReadWrite, Category = "RotationMatchingData") + float DesiredYaw = 0.0f; + + UPROPERTY(BlueprintReadWrite, Category = "RotationMatchingData") + uint8 AnimHasRotationLeft : 1 = true; +}; + USTRUCT(BlueprintType) struct FOLSTurnInPlaceAnimSet { diff --git a/Source/OLSAnimation/Public/Libraries/OLSLocomotionBPLibrary.h b/Source/OLSAnimation/Public/Libraries/OLSLocomotionBPLibrary.h index e06be97..b1d94d8 100644 --- a/Source/OLSAnimation/Public/Libraries/OLSLocomotionBPLibrary.h +++ b/Source/OLSAnimation/Public/Libraries/OLSLocomotionBPLibrary.h @@ -4,6 +4,7 @@ #include "CoreMinimal.h" #include "SequenceEvaluatorLibrary.h" +#include "Data/OLSAnimationData.h" #include "Data/OLSEnumLibrary.h" #include "Kismet/BlueprintFunctionLibrary.h" #include "OLSLocomotionBPLibrary.generated.h" @@ -29,6 +30,7 @@ public: // ~ Helpers ~ // * @note This function is useful for identifying key moments in animations where directional changes occur, * such as during character turns or sharp movements, ensuring smooth transitions or special handling. */ + UFUNCTION(BlueprintCallable, Category = "OLS|Function Library", meta=(BlueprintThreadSafe)) static float FindPivotTime(const UAnimSequenceBase* animSequence, const float sampleRate); /** @@ -54,7 +56,8 @@ public: // ~ Helpers ~ // * @return The interpolated time at which the curve reaches the specified value. Returns 0 if the curve is invalid or the value cannot be found. * * @note This function uses binary search to efficiently locate the curve value and linearly interpolates between keyframes for precision. - */ + */ + UFUNCTION(BlueprintCallable, Category = "OLS|Function Library", meta=(BlueprintThreadSafe)) static float GetTimeAtCurveValue(const UAnimSequenceBase* animSequence, const float& curveValue, FName curveName); /** @@ -178,6 +181,12 @@ public: static FVector PredictGroundMovementPivotLocation(const FVector& acceleration, const FVector& velocity, float groundFriction); + // UFUNCTION(BlueprintCallable,Category = "OLS|Function Library",meta=(BlueprintThreadSafe)) + // static float RotationMatching(const float deltaTime, const float interpSpeed, const float animRotAlpha, + // const FVector& acceleration, const float targetAngle, UPARAM(ref) FOLSRotationMatchingData& outRotationMatchingData, + // UPARAM(ref) float& outTargetRotationYaw); + + public: UFUNCTION(BlueprintCallable,BlueprintPure,Category = "OLS|Function Library",meta=(BlueprintThreadSafe))