89 - Smooth Rotation for Proxies

This commit is contained in:
Kingsmedia 2022-05-06 12:43:18 +02:00
parent db9ebc98fe
commit 3a5ca822aa
5 changed files with 99 additions and 14 deletions

View File

@ -37,7 +37,7 @@ void UBlasterAnimInstance::NativeUpdateAnimation(float DeltaSeconds)
bIsCrouched = BlasterCharacter->bIsCrouched;
bAiming = BlasterCharacter->IsAiming();
TurningInPlace = BlasterCharacter->GetTurningInPlace();
bRotateRootBone = BlasterCharacter->ShouldRotateRootBone();
// Offset Yaw for Strafing
FRotator AimRotation = BlasterCharacter->GetBaseAimRotation();
FRotator MovementRotation = UKismetMathLibrary::MakeRotFromX(BlasterCharacter->GetVelocity());

View File

@ -72,4 +72,7 @@ private:
UPROPERTY(BlueprintReadOnly, Category="Movement", meta=(AllowPrivateAccess = "true"))
bool bLocallyControlled;
UPROPERTY(BlueprintReadOnly, Category="Movement", meta=(AllowPrivateAccess = "true"))
bool bRotateRootBone;
};

View File

@ -55,6 +55,14 @@ void ABlasterCharacter::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& Ou
DOREPLIFETIME_CONDITION(ABlasterCharacter, OverlappingWeapon, COND_OwnerOnly);
}
void ABlasterCharacter::OnRep_ReplicatedMovement()
{
Super::OnRep_ReplicatedMovement();
SimProxiesTurn();
TimeSinceLastMovementReplication = 0.f;
}
void ABlasterCharacter::PostInitializeComponents()
{
Super::PostInitializeComponents();
@ -73,7 +81,7 @@ void ABlasterCharacter::PlayFireMontage(bool bAiming)
if (AnimInstance && FireWeaponMontage)
{
AnimInstance->Montage_Play(FireWeaponMontage);
FName SectionName = bAiming ? FName("RifleADS") : FName("RifleHip");
const FName SectionName = bAiming ? FName("RifleADS") : FName("RifleHip");
AnimInstance->Montage_JumpToSection(SectionName);
}
}
@ -100,7 +108,20 @@ void ABlasterCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
AimOffset(DeltaTime);
if (GetLocalRole() > ROLE_SimulatedProxy && IsLocallyControlled())
{
AimOffset(DeltaTime);
}
else
{
TimeSinceLastMovementReplication += DeltaTime;
if (TimeSinceLastMovementReplication > 0.25f)
{
OnRep_ReplicatedMovement();
}
CalculateAO_Pitch();
}
HideCameraIfCharacterClose();
}
@ -201,15 +222,14 @@ void ABlasterCharacter::AimOffset(float DeltaTime)
{
if (Combat && Combat->EquippedWeapon == nullptr) return;
FVector Velocity = GetVelocity();
Velocity.Z = 0.f;
float Speed = Velocity.Size();
bool bIsInAir = GetCharacterMovement()->IsFalling();
const float Speed = CalculateSpeed();
const bool bIsInAir = GetCharacterMovement()->IsFalling();
if (Speed == 0.f && !bIsInAir) // Standing still, not jumping
{
FRotator CurrentAimRotation = FRotator(0.f, GetBaseAimRotation().Yaw, 0.f);
FRotator DeltaAimRotation = UKismetMathLibrary::NormalizedDeltaRotator(CurrentAimRotation, StartingAimRotation);
bRotateRootBone = true;
const FRotator CurrentAimRotation = FRotator(0.f, GetBaseAimRotation().Yaw, 0.f);
const FRotator DeltaAimRotation = UKismetMathLibrary::NormalizedDeltaRotator(CurrentAimRotation, StartingAimRotation);
AO_Yaw = DeltaAimRotation.Yaw;
if (TurningInPlace == ETurningInPlace::ETIP_NotTurning)
{
@ -220,24 +240,67 @@ void ABlasterCharacter::AimOffset(float DeltaTime)
}
if (Speed > 0.f || bIsInAir) // Running or jumping
{
bRotateRootBone = false;
StartingAimRotation = FRotator(0.f, GetBaseAimRotation().Yaw, 0.f);
AO_Yaw = 0.f;
bUseControllerRotationYaw = true;
TurningInPlace = ETurningInPlace::ETIP_NotTurning;
}
CalculateAO_Pitch();
}
void ABlasterCharacter::CalculateAO_Pitch()
{
AO_Pitch = GetBaseAimRotation().Pitch;
// Fix pitch/yaw compression
if (AO_Pitch > 90.f && !IsLocallyControlled())
{
// map pitch from [270, 360) to [-90, 0)
FVector2d InRange(270.f, 360.f);
FVector2d OutRange(-90.f, 0.f);
const FVector2d InRange(270.f, 360.f);
const FVector2d OutRange(-90.f, 0.f);
AO_Pitch = FMath::GetMappedRangeValueClamped(InRange, OutRange, AO_Pitch);
}
}
void ABlasterCharacter::SimProxiesTurn()
{
if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return;
bRotateRootBone = false;
const float Speed = CalculateSpeed();
if (Speed > 0.f)
{
TurningInPlace = ETurningInPlace::ETIP_NotTurning;
return;
}
ProxyRotationLastFrame = ProxyRotation;
ProxyRotation = GetActorRotation();
ProxyYaw = UKismetMathLibrary::NormalizedDeltaRotator(ProxyRotation, ProxyRotationLastFrame).Yaw;
if (FMath::Abs(ProxyYaw) > TurnThreshold)
{
if (ProxyYaw > TurnThreshold)
{
TurningInPlace = ETurningInPlace::ETIP_Right;
}
else if (ProxyYaw < -TurnThreshold)
{
TurningInPlace = ETurningInPlace::ETIP_Left;
}
else
{
TurningInPlace = ETurningInPlace::ETIP_NotTurning;
}
return;
}
TurningInPlace = ETurningInPlace::ETIP_NotTurning;
}
void ABlasterCharacter::Jump()
{
if (bIsCrouched)
@ -273,7 +336,6 @@ void ABlasterCharacter::ServerEquipButtonPressed_Implementation()
void ABlasterCharacter::TurnInPlace(float DeltaTime)
{
// UE_LOG(LogTemp, Warning, TEXT("AO_Yaw: %f"), AO_Yaw);
if (AO_Yaw > 90.f)
{
TurningInPlace = ETurningInPlace::ETIP_Right;
@ -314,14 +376,15 @@ void ABlasterCharacter::MulticastHit_Implementation()
void ABlasterCharacter::HideCameraIfCharacterClose()
{
if (!IsLocallyControlled()) return;
if((FollowCamera->GetComponentLocation() - GetActorLocation()).Size() < CameraThreshold)
if ((FollowCamera->GetComponentLocation() - GetActorLocation()).Size() < CameraThreshold)
{
GetMesh()->SetVisibility(false);
if (Combat && Combat->EquippedWeapon && Combat->EquippedWeapon->GetWeaponMesh())
{
Combat->EquippedWeapon->GetWeaponMesh()->bOwnerNoSee = true;
}
} else
}
else
{
GetMesh()->SetVisibility(true);
if (Combat && Combat->EquippedWeapon && Combat->EquippedWeapon->GetWeaponMesh())
@ -331,6 +394,13 @@ void ABlasterCharacter::HideCameraIfCharacterClose()
}
}
float ABlasterCharacter::CalculateSpeed()
{
FVector Velocity = GetVelocity();
Velocity.Z = 0.f;
return Velocity.Size();
}
void ABlasterCharacter::SetOverlappingWeapon(AWeapon* Weapon)
{
if (OverlappingWeapon)

View File

@ -19,6 +19,7 @@ public:
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
virtual void PostInitializeComponents() override;
virtual void OnRep_ReplicatedMovement() override;
void PlayFireMontage(bool bAiming);
UFUNCTION(NetMulticast, Unreliable)
@ -35,7 +36,9 @@ protected:
void CrouchButtonPressed();
void AimButtonPressed();
void AimButtonReleased();
void CalculateAO_Pitch();
void AimOffset(float DeltaTime);
void SimProxiesTurn();
virtual void Jump() override;
void FireButtonPressed();
void FireButtonReleased();
@ -81,6 +84,14 @@ private:
UPROPERTY(EditAnywhere)
float CameraThreshold = 200.f;
bool bRotateRootBone;
float TurnThreshold = 0.8f;
FRotator ProxyRotationLastFrame;
FRotator ProxyRotation;
float ProxyYaw;
float TimeSinceLastMovementReplication;
float CalculateSpeed();
public:
void SetOverlappingWeapon(AWeapon* Weapon);
@ -92,4 +103,5 @@ public:
FORCEINLINE ETurningInPlace GetTurningInPlace() const { return TurningInPlace; }
FVector GetHitTarget() const;
FORCEINLINE UCameraComponent* GetFollowCamera() const { return FollowCamera; }
FORCEINLINE bool ShouldRotateRootBone() const { return bRotateRootBone; }
};