I got this working, but had to change engine code…
Not sure if this is the finest way, but i got no problems so far…
So “onClick”-events use the function “DeprojectScreenToWorld” from
\Engine\Source\Runtime\Engine\Private\GameplayStatics.cpp
In the function they use the LocalPlayer:
ULocalPlayer* const LP = Player ? Player->GetLocalPlayer() : nullptr;
I added two variables to the parent LocalPlayer class:
Engine\Source\Runtime\Engine\Classes\Engine\LocalPlayer.h
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
float LPScale;
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
FVector2D LPShift;
Like Slawek.Pudlis suggested I got my derived class MyLocalPlayer, where I edit the ProjectionMatrix in the CalcSceneView function. But there I also set the variables LPScale and LPShift of the parent LocalPlayer class:
FScaleMatrix scaleM(FVector(scale, scale, 1.0f));
FTranslationMatrix shiftM(FVector(shift.X, shift.Y, 0.0f));
LPScale = scale;
LPShift = shift;
UpdateProjectionMatrix(View, scaleM * shiftM);
After that I got the edited projection matrix and the localplayer has the scale and shift values. Now I got to change the DeprojectScreenToWorld function:
bool UGameplayStatics::DeprojectScreenToWorld(APlayerController const* Player, const FVector2D& ScreenPosition, FVector& WorldPosition, FVector& WorldDirection)
{
ULocalPlayer* const LP = Player ? Player->GetLocalPlayer() : nullptr;
if (LP && LP->ViewportClient)
{
// get the projection data
FSceneViewProjectionData ProjectionData;
if (LP->GetProjectionData(LP->ViewportClient->Viewport, eSSP_FULL, /*out*/ ProjectionData))
{
//-------Shift-and-Scale-Edit-------
FScaleMatrix scaleM(FVector(LP->LPScale, LP->LPScale, 1.0f));
FTranslationMatrix shiftM(FVector(LP->LPShift.X, LP->LPShift.Y, 0.0f));
FMatrix UpdatedMatrix = ProjectionData.ProjectionMatrix * scaleM * shiftM;
UpdatedMatrix = FTranslationMatrix(-ProjectionData.ViewOrigin) * ProjectionData.ViewRotationMatrix * UpdatedMatrix;
//----------------------------------
FMatrix const InvViewProjMatrix = UpdatedMatrix.InverseFast();
FSceneView::DeprojectScreenToWorld(ScreenPosition, ProjectionData.GetConstrainedViewRect(), InvViewProjMatrix, /*out*/ WorldPosition, /*out*/ WorldDirection);
return true;
}
}
// something went wrong, zero things and return false
WorldPosition = FVector::ZeroVector;
WorldDirection = FVector::ZeroVector;
return false;
}
Because this is working for me, I will mark this as the answer, but if you find a better way, feel free to correct me