Fixed bugs related to RootYawOffset

This commit is contained in:
LongLy 2024-10-23 20:34:02 -06:00
parent ac16f3093a
commit a54a3c8154
13 changed files with 1330 additions and 835 deletions

View File

@ -1,7 +1,7 @@
/Engine=C:/Program Files/Epic Games/UE_5.4/Engine/Shaders
/ShaderAutogen=H:/Projects/OLS/Intermediate/ShaderAutogen
/Plugin/GLTFExporter=C:/Program Files/Epic Games/UE_5.4/Engine/Plugins/Enterprise/GLTFExporter/Shaders
/Plugin/FX/Niagara=C:/Program Files/Epic Games/UE_5.4/Engine/Plugins/FX/Niagara/Shaders
/Plugin/ExrReaderShaders=C:/Program Files/Epic Games/UE_5.4/Engine/Plugins/Media/ImgMedia/Shaders
/Plugin/WmfMedia=C:/Program Files/Epic Games/UE_5.4/Engine/Plugins/Media/WmfMedia/Shaders
/Plugin/FX/Niagara=C:/Program Files/Epic Games/UE_5.4/Engine/Plugins/FX/Niagara/Shaders
/Plugin/Experimental/ChaosNiagara=C:/Program Files/Epic Games/UE_5.4/Engine/Plugins/Experimental/ChaosNiagara/Shaders

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

File diff suppressed because it is too large Load Diff

View File

@ -108,7 +108,7 @@ void UOLSBaseLayerAnimInstance::NativeBeginPlay()
if (LocomotionComponent)
{
RotationMode = LocomotionComponent->GetRotationMode();
bHasRotationModeChanged = true;
CurrentRootYawOffset = RootYawOffsetClamps.GetRootYawOffsetClamp(RotationMode);
}
});
}
@ -405,7 +405,7 @@ void UOLSBaseLayerAnimInstance::NativeThreadSafeUpdateRootYawOffset(const float
SetRootYawOffset(
UKismetMathLibrary::FloatSpringInterp(RootYawOffset,
0.f,
RootYawOffsetSprintState,
RootYawOffsetSpringState,
80.f,
1.f,
deltaSeconds,
@ -519,7 +519,7 @@ void UOLSBaseLayerAnimInstance::SetRootYawOffset(const float rootYawOffset)
return;
}
const FVector2D& rootYawOffsetClamp = (bIsCrouching ? RootYawOffsetAngleClamp_Crouching : RootYawOffsetAngleClamp_Standing);
const FVector2D& rootYawOffsetClamp = CurrentRootYawOffset.GetRootYawOffsetClamp(Stance);
const float normalRootYawOffset = UKismetMathLibrary::NormalizeAxis(rootYawOffset);
RootYawOffset = (rootYawOffsetClamp.X == rootYawOffsetClamp.Y) ? normalRootYawOffset : FMath::Clamp(normalRootYawOffset, rootYawOffsetClamp.X, rootYawOffsetClamp.Y);
@ -561,31 +561,33 @@ void UOLSBaseLayerAnimInstance::ProcessTurnYawCurve_ForwardFacing()
// When the animation blends in, we could have near-zero weights.
// When this value is goes up, and then down to 0, we know.
if (MaxTurnYawValue == 0.f)
if (MaxTurnYawValue != 0.f)
{
bHasReachedEndTurn = true;
}
return;
}
const float remainingTurnYawCurveValue = GetCurveValue(RemainingTurnYawCurveName);
TurnYawCurveValue = UKismetMathLibrary::SafeDivide(remainingTurnYawCurveValue, turnYawWeightCurveValue);
if (FMath::Abs(TurnYawCurveValue) > FMath::Abs(MaxTurnYawValue))
else
{
MaxTurnYawValue = TurnYawCurveValue;
}
const float remainingTurnYawCurveValue = GetCurveValue(RemainingTurnYawCurveName);
TurnYawCurveValue = UKismetMathLibrary::SafeDivide(remainingTurnYawCurveValue, turnYawWeightCurveValue);
// Avoid applying the curve delta when the curve first becomes relevant. E.g.
// When a turn animation starts, the previous curve value will be 0 and the current value will be 90,
// but no actual rotation has happened yet.
if (previousTurnYawCurveValue != 0.f)
{
const float actualAngle = UKismetMathLibrary::SafeDivide(LocalVelocityDirectionAngleWithOffset, TurnYawCurveValue) * TurnYawCurveValue - previousTurnYawCurveValue;
const float minAngle = FMath::Abs(LocalVelocityDirectionAngleWithOffset) * -1.f;
const float maxAngle = FMath::Abs(LocalVelocityDirectionAngleWithOffset);
// Reduce the target yaw offset by the amount of rotation from the turn animation.
SetRootYawOffset(RootYawOffset - FMath::Clamp(actualAngle, minAngle, maxAngle));
if (FMath::Abs(TurnYawCurveValue) > FMath::Abs(MaxTurnYawValue))
{
MaxTurnYawValue = TurnYawCurveValue;
}
// Avoid applying the curve delta when the curve first becomes relevant. E.g.
// When a turn animation starts, the previous curve value will be 0 and the current value will be 90,
// but no actual rotation has happened yet.
if (previousTurnYawCurveValue != 0.f)
{
const float actualAngle = UKismetMathLibrary::SafeDivide(LocalVelocityDirectionAngleWithOffset,
TurnYawCurveValue) * (TurnYawCurveValue - previousTurnYawCurveValue);
const float minAngle = FMath::Abs(LocalVelocityDirectionAngleWithOffset) * -1.f;
const float maxAngle = FMath::Abs(LocalVelocityDirectionAngleWithOffset);
// Reduce the target yaw offset by the amount of rotation from the turn animation.
SetRootYawOffset(RootYawOffset - FMath::Clamp(actualAngle, minAngle, maxAngle));
}
}
}

View File

@ -179,3 +179,13 @@ const FOLSGaitAnimSets* FOLSStanceAnimSets::SelectGaitAnimSetByGait(const EOLSGa
{
return GaitAnimSets.Find(gait);
}
const FVector2D& FOLSRootYawOffsetClamp::GetRootYawOffsetClamp(const EOLSStance stance) const
{
return (stance == EOLSStance::EStanding ? RootYawOffsetClamp_Standing : RootYawOffsetClamp_Crouching);
}
const FOLSRootYawOffsetClamp& FOLSRootYawOffsetClamps::GetRootYawOffsetClamp(const EOLSRotationMode& rotationMode) const
{
return RootYawOffsetClamps.FindChecked(rotationMode);
}

View File

@ -293,7 +293,7 @@ protected:
float RootYawOffset = 0.f;
UPROPERTY(BlueprintReadOnly, Category = "ThreadSafe|TurnInPlaceData")
FFloatSpringState RootYawOffsetSprintState;
FFloatSpringState RootYawOffsetSpringState;
UPROPERTY(BlueprintReadWrite, Category = "ThreadSafe|TurnInPlaceData")
EOLSRootYawOffsetMode RootYawOffsetMode = EOLSRootYawOffsetMode::EBlendOut;
@ -307,13 +307,13 @@ protected:
UPROPERTY(BlueprintReadOnly, Category = "ThreadSafe|TurnInPlaceData")
float TurnInPlaceRecoveryDirection = 0.f;
UPROPERTY(BlueprintReadOnly, Category = "ThreadSafe|TurnInPlaceData")
UPROPERTY(BlueprintReadWrite, Category = "ThreadSafe|TurnInPlaceData")
float MaxTurnYawValue = 0.f;
UPROPERTY(BlueprintReadOnly, Category = "ThreadSafe|TurnInPlaceData")
float CachedTurnYawCurveValue = 0.f;
UPROPERTY(BlueprintReadOnly, Category = "ThreadSafe|TurnInPlaceData")
UPROPERTY(BlueprintReadWrite, Category = "ThreadSafe|TurnInPlaceData")
uint8 bHasReachedEndTurn : 1 = false;
protected:
@ -409,6 +409,9 @@ protected:
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Settings|TurnInPlaceData")
FName RemainingTurnYawCurveName = NAME_None;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Settings|TurnInPlaceData")
FOLSRootYawOffsetClamps RootYawOffsetClamps;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Settings|TurnInPlaceData")
FVector2D RootYawOffsetAngleClamp_Standing = FVector2D(-120.f, 100.f);
@ -447,4 +450,8 @@ protected: // References
TObjectPtr<class UOLSLocomotionComponent> LocomotionComponent = nullptr;
TScriptInterface<class IOLSMoveableInterface> MoveableInterface = nullptr;
protected:
FOLSRootYawOffsetClamp CurrentRootYawOffset;
};

View File

@ -280,3 +280,36 @@ public:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Stance Anim Sets")
FOLSAimAnimSet AimAnimSet;
};
USTRUCT(BlueprintType)
struct FOLSRootYawOffsetClamp
{
GENERATED_BODY()
public:
const FVector2D& GetRootYawOffsetClamp(const EOLSStance stance) const;
public:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Root Yaw Offset Clamp")
FVector2D RootYawOffsetClamp_Standing = FVector2D::ZeroVector;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Root Yaw Offset Clamp")
FVector2D RootYawOffsetClamp_Crouching = FVector2D::ZeroVector;
};
USTRUCT(BlueprintType)
struct FOLSRootYawOffsetClamps
{
GENERATED_BODY()
public:
const FOLSRootYawOffsetClamp& GetRootYawOffsetClamp(const EOLSRotationMode& rotationMode) const;
public:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Stance Anim Sets")
TMap<EOLSRotationMode, FOLSRootYawOffsetClamp> RootYawOffsetClamps;
};

View File

@ -28,6 +28,7 @@ void AOLSCharacter::BeginPlay()
{
Super::BeginPlay();
LocomotionComponent->GetOnRotationModeChangedNativeDelegate().AddUObject(this, &ThisClass::OnRotationModeChanged);
}
// Called every frame
@ -81,3 +82,25 @@ UAnimInstance* AOLSCharacter::GetAnimInstance() const
{
return (GetMesh() ? GetMesh()->GetAnimInstance() : nullptr);
}
void AOLSCharacter::OnRotationModeChanged(const EOLSRotationMode& prevrRotationMode)
{
switch (LocomotionComponent->GetRotationMode())
{
case EOLSRotationMode::EVelocityDirection:
GetCharacterMovement()->bOrientRotationToMovement = true;
bUseControllerRotationYaw = false;
GetCharacterMovement()->bUseControllerDesiredRotation = false;
break;
case EOLSRotationMode::ELookingDirection:
GetCharacterMovement()->bOrientRotationToMovement = false;
bUseControllerRotationYaw = true;
GetCharacterMovement()->bUseControllerDesiredRotation = false;
break;
case EOLSRotationMode::EAiming:
GetCharacterMovement()->bOrientRotationToMovement = false;
bUseControllerRotationYaw = true;
GetCharacterMovement()->bUseControllerDesiredRotation = true;
break;
}
}

View File

@ -3,6 +3,7 @@
#pragma once
#include "CoreMinimal.h"
#include "Data/OLSLocomotionData.h"
#include "GameFramework/Character.h"
#include "Interfaces/OLSAnimationInterface.h"
#include "Interfaces/OLSMoveableInterface.h"
@ -50,6 +51,10 @@ public:
virtual class UAnimInstance* GetAnimInstance() const override;
//~ IOLSAnimationInterface END
protected:
virtual void OnRotationModeChanged(const EOLSRotationMode& prevrRotationMode);
protected:
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Components)