Fix rotations so character faces their previous direction when switching grav direction

This commit is contained in:
Kevin Poretti 2023-01-07 23:16:39 -05:00
parent bd20b78a3b
commit 8ac4271602
4 changed files with 46 additions and 20 deletions

Binary file not shown.

View File

@ -103,5 +103,20 @@ void AGSCharacter::ChangeGravityDirection(const FInputActionValue& Value)
FVector2D GravityDirection = Value.Get<FVector2D>(); FVector2D GravityDirection = Value.Get<FVector2D>();
FVector NewCharacterUpDirection(0.0f, -GravityDirection.X, -GravityDirection.Y); FVector NewCharacterUpDirection(0.0f, -GravityDirection.X, -GravityDirection.Y);
FRotator CharRot = GetActorRotation();
if(GetCharacterMovement<UGSCharacterMovementComponent>()->IsCharacterUpAlignedToWorldUp())
{
CharRot = FRotator(0.0f, CharRot.Yaw, 0.0f);
}
else
{
CharRot = FRotator(CharRot.Pitch, 0.0f, 0.0f);
}
float NewRoll = GetCharacterMovement<UGSCharacterMovementComponent>()->GetRollFromCharacterUpDir(NewCharacterUpDirection);
FRotator RollRot = UKismetMathLibrary::RotatorFromAxisAndAngle(FVector::ForwardVector, NewRoll);
SetActorRotation(UKismetMathLibrary::ComposeRotators(RollRot, CharRot));
GetCharacterMovement<UGSCharacterMovementComponent>()->SetCharacterUpDirection(NewCharacterUpDirection); GetCharacterMovement<UGSCharacterMovementComponent>()->SetCharacterUpDirection(NewCharacterUpDirection);
} }

View File

@ -658,6 +658,25 @@ bool UGSCharacterMovementComponent::IsCharacterUpAlignedToWorldUp() const
return FMath::Abs(CharacterUpDirection.Dot(FVector::UpVector)) > UE_KINDA_SMALL_NUMBER; return FMath::Abs(CharacterUpDirection.Dot(FVector::UpVector)) > UE_KINDA_SMALL_NUMBER;
} }
float UGSCharacterMovementComponent::GetRollFromCharacterUpDir(const FVector& UpDir) const
{
float Rot = 0.0f;
if(CharacterUpDirection.Dot(FVector::DownVector) > UE_KINDA_SMALL_NUMBER)
{
Rot = 180.0f;
}
else if (CharacterUpDirection.Dot(FVector::RightVector) > UE_KINDA_SMALL_NUMBER)
{
Rot = 90.0f;
}
else if (CharacterUpDirection.Dot(FVector::LeftVector) > UE_KINDA_SMALL_NUMBER)
{
Rot = 270.0f;
}
return Rot;
}
void UGSCharacterMovementComponent::SetCharacterUpDirection(FVector NewUpDirection) void UGSCharacterMovementComponent::SetCharacterUpDirection(FVector NewUpDirection)
{ {
@ -842,21 +861,7 @@ void UGSCharacterMovementComponent::PhysicsRotation(float DeltaTime)
DesiredRotation.Pitch = IsCharacterUpAlignedToWorldUp() ? 0.f : FRotator::NormalizeAxis(DesiredRotation.Pitch); DesiredRotation.Pitch = IsCharacterUpAlignedToWorldUp() ? 0.f : FRotator::NormalizeAxis(DesiredRotation.Pitch);
DesiredRotation.Yaw = IsCharacterUpAlignedToWorldUp() ? FRotator::NormalizeAxis(DesiredRotation.Yaw) : 0.f; DesiredRotation.Yaw = IsCharacterUpAlignedToWorldUp() ? FRotator::NormalizeAxis(DesiredRotation.Yaw) : 0.f;
DesiredRotation.Roll = GetRollFromCharacterUpDir(CharacterUpDirection);
float Rot = 0.0f;
if(CharacterUpDirection.Dot(FVector::DownVector) > UE_KINDA_SMALL_NUMBER)
{
Rot = 180.0f;
}
else if (CharacterUpDirection.Dot(FVector::RightVector) > UE_KINDA_SMALL_NUMBER)
{
Rot = 90.0f;
}
else if (CharacterUpDirection.Dot(FVector::LeftVector) > UE_KINDA_SMALL_NUMBER)
{
Rot = 270.0f;
}
DesiredRotation.Roll = Rot;
DebugDesiredRotation = FString::Printf(TEXT("Desired Rotation after keeping it vertical: %s"), *DesiredRotation.ToString()); DebugDesiredRotation = FString::Printf(TEXT("Desired Rotation after keeping it vertical: %s"), *DesiredRotation.ToString());
GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Cyan, DebugDesiredRotation); GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Cyan, DebugDesiredRotation);

View File

@ -19,9 +19,18 @@ class GRAVITYSTOMPGAME_API UGSCharacterMovementComponent : public UCharacterMove
public: public:
UGSCharacterMovementComponent(); UGSCharacterMovementComponent();
UFUNCTION(BlueprintPure)
FORCEINLINE FVector GetCharacterUpDirection() const { return CharacterUpDirection; }
UFUNCTION(BlueprintCallable) UFUNCTION(BlueprintCallable)
void SetCharacterUpDirection(FVector NewUpDirection); void SetCharacterUpDirection(FVector NewUpDirection);
UFUNCTION(BlueprintPure)
float GetRollFromCharacterUpDir(const FVector& UpDir) const;
UFUNCTION(BlueprintPure)
FORCEINLINE bool IsCharacterUpAlignedToWorldUp() const;
// UCharacterMovementComponent interface // UCharacterMovementComponent interface
virtual FVector ConstrainInputAcceleration(const FVector& InputAcceleration) const override; virtual FVector ConstrainInputAcceleration(const FVector& InputAcceleration) const override;
@ -59,7 +68,4 @@ public:
private: private:
FVector CharacterUpDirection = FVector::UpVector; FVector CharacterUpDirection = FVector::UpVector;
UFUNCTION(BlueprintPure)
FORCEINLINE bool IsCharacterUpAlignedToWorldUp() const;
}; };