UnrealC++でマウスの位置をワールド座標に変換するには「DeprojectMousePositionToWorld」を使用します
bool APlayerController::DeprojectMousePositionToWorld(FVector& WorldLocation, FVector& WorldDirection) const
{
ULocalPlayer* const LocalPlayer = GetLocalPlayer();
if (LocalPlayer && LocalPlayer->ViewportClient)
{
FVector2D ScreenPosition;
if (LocalPlayer->ViewportClient->GetMousePosition(ScreenPosition))
{
return UGameplayStatics::DeprojectScreenToWorld(this, ScreenPosition, WorldLocation, WorldDirection);
}
}
return false;
}
BPでは「Convert Mouse Location To World Space」ノードを使用しますがC++では関数名が違います。
「DeprojectMousePositionToWorld」で取得できるのは
・ワールド座標
・マウスの方向ベクトル(正規化済み)
を取得することができます。
関数をたどっていくと「FSceneView::DeprojectScreenToWorld」の1516行目にGetSafeNormal()と
書いてあり正規化済みの方向ベクトルが取得できます。
void FSceneView::DeprojectScreenToWorld(const FVector2D& ScreenPos, const FIntRect& ViewRect, const FMatrix& InvViewProjMatrix, FVector& out_WorldOrigin, FVector& out_WorldDirection)
{
float PixelX = FMath::TruncToFloat(ScreenPos.X);
float PixelY = FMath::TruncToFloat(ScreenPos.Y);
const float NormalizedX = (PixelX - ViewRect.Min.X) / ((float)ViewRect.Width());
const float NormalizedY = (PixelY - ViewRect.Min.Y) / ((float)ViewRect.Height());
const float ScreenSpaceX = (NormalizedX - 0.5f) * 2.0f;
const float ScreenSpaceY = ((1.0f - NormalizedY) - 0.5f) * 2.0f;
const FVector4 RayStartProjectionSpace = FVector4(ScreenSpaceX, ScreenSpaceY, 1.0f, 1.0f);
const FVector4 RayEndProjectionSpace = FVector4(ScreenSpaceX, ScreenSpaceY, 0.01f, 1.0f);
const FVector4 HGRayStartWorldSpace = InvViewProjMatrix.TransformFVector4(RayStartProjectionSpace);
const FVector4 HGRayEndWorldSpace = InvViewProjMatrix.TransformFVector4(RayEndProjectionSpace);
FVector RayStartWorldSpace(HGRayStartWorldSpace.X, HGRayStartWorldSpace.Y, HGRayStartWorldSpace.Z);
FVector RayEndWorldSpace(HGRayEndWorldSpace.X, HGRayEndWorldSpace.Y, HGRayEndWorldSpace.Z);
if (HGRayStartWorldSpace.W != 0.0f)
{
RayStartWorldSpace /= HGRayStartWorldSpace.W;
}
if (HGRayEndWorldSpace.W != 0.0f)
{
RayEndWorldSpace /= HGRayEndWorldSpace.W;
}
// ここで、GetSafeNormal()で正規化済みのベクトルを求めてる
const FVector RayDirWorldSpace = (RayEndWorldSpace - RayStartWorldSpace).GetSafeNormal();
out_WorldOrigin = RayStartWorldSpace;
out_WorldDirection = RayDirWorldSpace;

