This is what I came up with after some experimenting.
InterpSpeed can be tweaked to achieve optimal smoothness.
#MyPawn.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "MyPawn.generated.h"
class UCameraComponent;
UCLASS()
class TEST_API AMyPawn : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
AMyPawn();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
private:
UPROPERTY()
USceneComponent* SceneComponent;
UPROPERTY()
UCameraComponent* CameraComponent;
float InterpSpeed;
float DeltaYaw;
float DeltaPitch;
};
#MyPawn.cpp
#include "MyPawn.h"
#include "Camera/CameraComponent.h"
// Sets default values
AMyPawn::AMyPawn()
: InterpSpeed(20.0f)
, DeltaYaw(0.0f)
, DeltaPitch(0.0f)
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
SceneComponent = CreateDefaultSubobject<USceneComponent>(TEXT("Scene"));
RootComponent = SceneComponent;
CameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
CameraComponent->SetupAttachment(SceneComponent);
}
// Called when the game starts or when spawned
void AMyPawn::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AMyPawn::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// Get current pitch and yaw
float CurYaw = SceneComponent->RelativeRotation.Yaw;
float CurPitch = CameraComponent->RelativeRotation.Pitch;
// Get delta from mouse axis
DeltaYaw += GetInputAxisValue(TEXT("Look_Yaw"));
DeltaPitch += GetInputAxisValue(TEXT("Look_Pitch"));
// Clamp Pitch to (-90, 90)
DeltaPitch = FMath::Clamp(CurPitch + DeltaPitch, -89.99f, 89.99f) - CurPitch;
// Interpolate the delta
float CurDeltaYaw = DeltaYaw - FMath::FInterpTo(DeltaYaw, 0.0f, DeltaTime, InterpSpeed);
float CurDeltaPitch = DeltaPitch - FMath::FInterpTo(DeltaPitch, 0.0f, DeltaTime, InterpSpeed);
// Rotate camera
SceneComponent->AddLocalRotation(FRotator(0.0f, CurDeltaYaw, 0.0f));
CameraComponent->AddLocalRotation(FRotator(CurDeltaPitch, 0.0f, 0.0f));
// Subtract the rotation we did from the remaining delta
DeltaYaw -= CurDeltaYaw;
DeltaPitch -= CurDeltaPitch;
}
// Called to bind functionality to input
void AMyPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
PlayerInputComponent->BindAxis(TEXT("Look_Yaw"));
PlayerInputComponent->BindAxis(TEXT("Look_Pitch"));
}
Does this work for blueprint in the same way or does it need some modification? I’d like to use the add controller yaw input (or pitch input) if possible since it’s probably easier.