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; bIsCrouched = BlasterCharacter->bIsCrouched;
bAiming = BlasterCharacter->IsAiming(); bAiming = BlasterCharacter->IsAiming();
TurningInPlace = BlasterCharacter->GetTurningInPlace(); TurningInPlace = BlasterCharacter->GetTurningInPlace();
bRotateRootBone = BlasterCharacter->ShouldRotateRootBone();
// Offset Yaw for Strafing // Offset Yaw for Strafing
FRotator AimRotation = BlasterCharacter->GetBaseAimRotation(); FRotator AimRotation = BlasterCharacter->GetBaseAimRotation();
FRotator MovementRotation = UKismetMathLibrary::MakeRotFromX(BlasterCharacter->GetVelocity()); FRotator MovementRotation = UKismetMathLibrary::MakeRotFromX(BlasterCharacter->GetVelocity());

View File

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

View File

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