Hey,
I’m doing something simular, reimplemented a blueprint sample/tutorial i found for doing this in C++ in a bit different way …
i assume your pawn blueprint has allready UseControllerRotationPitch/Yaw/Roll turned off?
If u are making a single player game, remove the ServerSetAimOffset()
I’m using this cause i dont use the GetAimOffset method used in the animation blueprint.
For some reasson the method used in the ShooterGame example causing issues when i change the view target to my weapon camera (ADS view)
I use the AimPitch/AimYaw variables directly in my animation blueprint
Header File
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Transient, Replicated, Category = "Character")
float AimPitch;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Transient, Replicated, Category = "Character")
float AimYaw;
/** Flags used by the aim offset calculation. */
uint32 bIsInAimRotation : 1;
Source file
void ASwatCharacter::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
// Calculate the aim offsets
if (IsLocallyControlled())
{
// Save the current aim pitch and yaw
float SavedAimPitch = AimPitch;
float SavedAimYaw = AimYaw;
// Update the aim offset
FRotator ControlRotation = GetControlRotation();
FRotator ActorRotation = GetActorRotation();
FRotator DeltaRotation = ControlRotation - ActorRotation;
DeltaRotation.Normalize();
// Interpolate the current and new aim offsets for smoothing
FRotator CurrentAimOffset(AimPitch, AimYaw, 0.0f);
FRotator UpdatedAimOffset = FMath::RInterpTo(CurrentAimOffset, DeltaRotation, DeltaSeconds, 15.0f);
AimPitch = UpdatedAimOffset.Pitch;
AimYaw = UpdatedAimOffset.Yaw;
// Notify the server about the new aim offset
if (Role < ROLE_Authority && (AimPitch != SavedAimPitch || AimYaw != SavedAimYaw))
{
ServerSetAimOffset(AimPitch, AimYaw);
}
}
}
bool ASwatCharacter::ServerSetAimOffset_Validate(float AimPitch, float AimYaw)
{
return true;
}
void ASwatCharacter::ServerSetAimOffset_Implementation(float InAimPitch, float InAimYaw)
{
AimPitch = InAimPitch;
AimYaw = InAimYaw;
}
Finally i update the pawn rotation by overriding the FaceRotation method of ACharacter
do not call Super::FaceRotation, from the comment line “Update the actor rotation”, the code is copied from the ACharacter class.
In the base class, when non of the UseControlRotations are used, the SetRotation will not be called.
void ASwatCharacter::FaceRotation(FRotator NewControlRotation, float DeltaTime)
{
// Update the actor rotation based on the aim offset
FRotator ControlRotation = GetControlRotation();
FRotator ActorRotation = GetActorRotation();
FRotator ControlYawRotation(0.0f, ControlRotation.Yaw, 0.0f);
FRotator ActorYawRotation(0.0f, ActorRotation.Yaw, 0.0f);
FRotator YawDeltaRotation = ControlYawRotation - ActorYawRotation;
YawDeltaRotation.Normalize();
FRotator AimRotation = FMath::RInterpTo(FRotator::ZeroRotator, YawDeltaRotation, DeltaTime, 5.0f);
if (FMath::Abs(YawDeltaRotation.Yaw) >= 70.0f || bIsInAimRotation || GetVelocity().Size() > 0.0f)
{
AddActorWorldRotation(AimRotation);
bIsInAimRotation = !FMath::IsNearlyEqual(YawDeltaRotation.Yaw, 0.0f, 2.0f);
}
// Update the actor rotation
const FRotator CurrentRotation = GetActorRotation();
if (!bUseControllerRotationPitch)
{
NewControlRotation.Pitch = CurrentRotation.Pitch;
}
if (!bUseControllerRotationYaw)
{
NewControlRotation.Yaw = CurrentRotation.Yaw;
}
if (!bUseControllerRotationRoll)
{
NewControlRotation.Roll = CurrentRotation.Roll;
}
SetActorRotation(NewControlRotation);
}