Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#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;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment