Skip to content

Instantly share code, notes, and snippets.

@Vatyx
Created June 27, 2021 23:29
Show Gist options
  • Save Vatyx/a3b32ed49506e923863d8f6ded438f10 to your computer and use it in GitHub Desktop.
Save Vatyx/a3b32ed49506e923863d8f6ded438f10 to your computer and use it in GitHub Desktop.
#include "ViewmodelSkeletalMeshComponent.h"
#include "Kismet/GameplayStatics.h"
void UViewmodelSkeletalMeshComponent::BeginPlay()
{
Super::BeginPlay();
PlayerController = UGameplayStatics::GetPlayerController(this, 0);
if (PlayerController != nullptr)
{
PlayerCameraManager = PlayerController->PlayerCameraManager;
}
}
FMatrix UViewmodelSkeletalMeshComponent::GetRenderMatrix() const
{
if (PlayerController == nullptr || PlayerCameraManager == nullptr)
{
return Super::GetRenderMatrix();
}
const float CurrentFOV = PlayerCameraManager->GetFOVAngle();
const float ViewmodelFOV = DesiredViewmodelFOV;
const float CurrentHalfFOVRadians = FMath::DegreesToRadians(FMath::Max(0.001f, CurrentFOV)) / 2.0f;
const float DesiredHalfFOVRadians = FMath::DegreesToRadians(FMath::Max(0.001f, ViewmodelFOV)) / 2.0f;
const float FOVRatio = CurrentHalfFOVRadians / DesiredHalfFOVRadians;
FVector ViewOrigin;
FRotator ViewRotation;
PlayerController->GetPlayerViewPoint(ViewOrigin, ViewRotation);
FMatrix ViewRotationMatrix = FInverseRotationMatrix(ViewRotation) * FMatrix(
FPlane(0, 0, 1, 0),
FPlane(1, 0, 0, 0),
FPlane(0, 1, 0, 0),
FPlane(0, 0, 0, 1));
if (!ViewRotationMatrix.GetOrigin().IsNearlyZero(0.0f))
{
ViewOrigin += ViewRotationMatrix.InverseTransformPosition(FVector::ZeroVector);
ViewRotationMatrix = ViewRotationMatrix.RemoveTranslation();
}
const FMatrix ViewMatrix = FTranslationMatrix(-ViewOrigin) * ViewRotationMatrix;
const FMatrix InverseViewMatrix = FTranslationMatrix(-ViewMatrix.GetOrigin()) * ViewMatrix.RemoveTranslation().GetTransposed();
const FMatrix PerspectiveAdjustmentMatrix = FMatrix(
FPlane(FOVRatio, 0, 0, 0),
FPlane(0, FOVRatio, 0, 0),
FPlane(0, 0, 1, 0),
FPlane(0, 0, 0, 1));
const FMatrix AdjustedRenderMatrix = GetComponentToWorld().ToMatrixWithScale() * ViewMatrix * PerspectiveAdjustmentMatrix * InverseViewMatrix;
return AdjustedRenderMatrix;
}
#pragma once
#include "CoreMinimal.h"
#include "Components/SkeletalMeshComponent.h"
#include "ViewmodelSkeletalMeshComponent.generated.h"
UCLASS(BlueprintType, meta = (BlueprintSpawnableComponent))
class MYPROJECT_API UViewmodelSkeletalMeshComponent : public USkeletalMeshComponent
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere)
float DesiredViewmodelFOV = 70.0f;
protected:
virtual void BeginPlay() override;
virtual FMatrix GetRenderMatrix() const override;
private:
UPROPERTY()
APlayerController* PlayerController;
UPROPERTY()
APlayerCameraManager* PlayerCameraManager;
};
@YidustGood
Copy link

This code performs well in UE4.27.2, but once it is transplanted to UE5, it will cause animation misalignment. For example, when the weapon FOV is 70 and the field FOV is 90, the weapon animation will not be normal. At this time, if the field FOV is changed to 70FOV, the animation will return to normal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment