This is a report about a bug and a work-around.
When using SteamVR (it might also apply to other VR platforms, I did not check) UMG can’t correctly translate mouse coordinates to screenspace coordinates, because the viewport information it uses is set by SteamVRHMD.cpp.
Blueprint nodes like GetWindowClientSize, GetViewportSize (+GetViewportScale), and AbsoluteToViewport don’t give accurate information at that point anymore either. GetMousePositionOnPlatform does still seem to work correctly, but that still requires accurate knowledge about the coordinates and dimensions of the window.
It is worth noting that I wrote this thread largely here because it took quite some time to debug, and I don’t want to have to go through that again, and I don’t see why anyone else should have to. With a bit of luck I’ll have time to report a proper bug report, but given that performing interactions with UMG widgets using the mouse might not be the most common thing to do in VR projects, I wouldn’t expect a bug report like that to receive a lot of priority.
It is possible to work around it with a little bit of C++:
FVector4 rect = FVector4(0, 0, 0, 0);
TSharedPtr<SWindow> TopLevelWindow = FSlateApplication::Get().GetActiveTopLevelWindow();
if (TopLevelWindow.IsValid())
{
FSlateRect coordinates = TopLevelWindow->GetClientRectInScreen();
rect = FVector4(coordinates.Left, coordinates.Top, coordinates.Right - coordinates.Left, coordinates.Bottom - coordinates.Top);
}
return rect;
(There might be a neater way to pass it to Blueprints than through an FVector4, but I leave that as an exercise for the reader.)
Be sure to
#include "Widgets\SWindow.h"
#include "Framework\Application\SlateApplication.h"
You may also need to add “Engine”, “SlateCore”, and “Slate” to AdditionalDependencies in the uproject file, or plugin file. You probably don’t need all of them, but it’s been a long day, and I don’t want to wait for a bunch more compilations to find out for sure. Just try it with “Slate” only, might well work. (I needed the first two for other approaches of getting access to SWindow), which didn’t work in PIE)
That still leaves the challenge of displaying UMG through the spectator view (to prevent it from getting displayed in the HMD), by passing the Render Target of a widget to SetSpectatorScreenTexture, but there’s already a little bit of information about that in the form of Riley Florence’s video. Oh and remember that you need to tell playercontroller 0 to show the mouse cursor.