For those who has T-POSE issue, I have implemented first person camera mode class as below. The logic is like for the first tick setting camera a little bit distant to character (like detaching from character and moving out) then in the next tick attaching it to the socket (FP_Camera in my case).
In my case
h. file;
#pragma once
#include "Camera/LyraCameraMode.h"
#include "LyraCameraMode_FirstPerson.generated.h"
/**
* ULyraCameraMode_FirstPerson
*
* A basic first person camera mode.
*/
UCLASS(Abstract, Blueprintable)
class ULyraCameraMode_FirstPerson : public ULyraCameraMode
{
GENERATED_BODY()
public:
ULyraCameraMode_FirstPerson();
protected:
virtual void UpdateView(float DeltaTime) override;
virtual void OnActivation() override;
virtual FVector GetPivotLocation() const override;
private:
void OnActivationNextTick();
bool bIsFirstTick;
};
cpp. file;
#include "Camera/LyraCameraMode_FirstPerson.h"
#include "GameFramework/Character.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(LyraCameraMode_FirstPerson)
ULyraCameraMode_FirstPerson::ULyraCameraMode_FirstPerson()
{
}
void ULyraCameraMode_FirstPerson::OnActivation()
{
bIsFirstTick = true;
GetWorld()->GetTimerManager().SetTimerForNextTick(this, &ULyraCameraMode_FirstPerson::OnActivationNextTick);
}
void ULyraCameraMode_FirstPerson::UpdateView(float DeltaTime)
{
FVector PivotLocation = GetPivotLocation();
FRotator PivotRotation = GetPivotRotation();
PivotRotation.Pitch = FMath::ClampAngle(PivotRotation.Pitch, ViewPitchMin, ViewPitchMax);
View.Location = PivotLocation;
View.Rotation = PivotRotation;
View.ControlRotation = View.Rotation;
View.FieldOfView = FieldOfView;
if (bIsFirstTick)
{
// This will simulate the camera like it has a distance to the character at the first tick, play with -200.f if it doesn't work
View.Location = PivotLocation + PivotRotation.RotateVector(FVector(-200.f, 0.f, 0.f));
}
}
FVector ULyraCameraMode_FirstPerson::GetPivotLocation() const
{
const AActor* TargetActor = GetTargetActor();
check(TargetActor);
if (const APawn* TargetPawn = Cast<APawn>(TargetActor))
{
// Get mesh socket location for first person camera
if (const ACharacter* TargetCharacter = Cast<ACharacter>(TargetPawn))
{
return TargetCharacter->GetMesh()->GetSocketLocation("FP_Camera");
}
return TargetPawn->GetPawnViewLocation();
}
return TargetActor->GetActorLocation();
}
void ULyraCameraMode_FirstPerson::OnActivationNextTick()
{
bIsFirstTick = false;
}