I’ve made a working prototype using materials and this is undoubtedly the best looking effect as it can be antialiased unlike the Canvas solution.
Here’s the code for the function that returns the 4 camera corners if you don’t already have it:
TArray<FVector2D> UGameUtility::DeprojectScreenCornersToPlane(
APlayerController* PlayerController,
FVector2D Offset,
float MinimapScale,
float ZPlane
)
{
TArray<FVector2D> MinimapPoints;
if (!PlayerController)
{
return MinimapPoints;
}
// Get viewport size
FVector2D ViewportSize;
GEngine->GameViewport->GetViewportSize(ViewportSize);
if (ViewportSize.IsZero())
{
return MinimapPoints;
}
// Define 4 screen corners
TArray<FVector2D> ScreenCorners = {
FVector2D(0.f, 0.f), // Top-left
FVector2D(ViewportSize.X, 0.f), // Top-right
FVector2D(ViewportSize.X, ViewportSize.Y), // Bottom-right
FVector2D(0.f, ViewportSize.Y), // Bottom-left
};
for (const FVector2D& ScreenPos : ScreenCorners)
{
FVector WorldOrigin, WorldDirection;
if (PlayerController->DeprojectScreenPositionToWorld(ScreenPos.X, ScreenPos.Y, WorldOrigin, WorldDirection))
{
if (!FMath::IsNearlyZero(WorldDirection.Z))
{
float t = (ZPlane - WorldOrigin.Z) / WorldDirection.Z;
FVector WorldPoint = (WorldOrigin + t * WorldDirection);
// Convert to minimap space
float MinimapX = WorldPoint.Y * MinimapScale + Offset.X;
float MinimapY = -WorldPoint.X * MinimapScale + Offset.Y;
MinimapPoints.Add(FVector2D(MinimapX, MinimapY));
}
}
}
return MinimapPoints;
}
(This assumes that the minimap is static and the world is center on origin)
The material:
The update function should look like this.