Hey guys,
I've got good and bad news.
The bad news is that a proper fix for this requires an Engine patch. I'll contact Epic with a pull request, because I think this change is necessary for anyone that wants to implement custom controls with hover over behavior and non rectangular shape.
The first bit of good news is that the change is relatively simple, so I'll attach the patch, but I've already found that buttons don't behave correctly with it. The button widget is fixed in the patch, but there may be other widgets that behave incorrectly as well. Also, this can only be done if you have the source code from GitHub, and not with Epic Games Launcher versions.
The second bit of good news is that I've exposed a workaround that you guys can implement in your PlayerController class. It involves a new function I just committed to GitHub, and all you have to do is to override the function IsInViewportClient in your player controller like this:
bool IsInViewportClient(UGameViewportClient* ViewportClient) const override
{
return Super::IsInViewportClient(ViewportClient) || NoesisIsViewportHovered(ViewportClient);
}
It's possible the new function requires some tweaking, but hopefully this will unblock you and allow you to keep working.
Here's the Engine code patch, in case you want to try this:
diff --git a/Engine/Source/Runtime/Slate/Private/Framework/Application/SlateApplication.cpp b/Engine/Source/Runtime/Slate/Private/Framework/Application/SlateApplication.cpp
index 7646131..03906b9 100644
--- a/Engine/Source/Runtime/Slate/Private/Framework/Application/SlateApplication.cpp
+++ b/Engine/Source/Runtime/Slate/Private/Framework/Application/SlateApplication.cpp
@@ -5366,6 +5366,7 @@ bool FSlateApplication::RoutePointerMoveEvent(const FWidgetPath& WidgetsUnderPoi
bool bHandled = false;
+ FWidgetPath CurrentWidgetsUnderCursor;
FWeakWidgetPath LastWidgetsUnderCursor;
// User asked us to detect a drag.
@@ -5520,6 +5521,10 @@ bool FSlateApplication::RoutePointerMoveEvent(const FWidgetPath& WidgetsUnderPoi
return TempReply;
});
bHandled = Reply.IsEventHandled();
+ if (bHandled)
+ {
+ CurrentWidgetsUnderCursor = WidgetsUnderPointer.GetPathDownTo(Reply.GetHandler().ToSharedRef());
+ }
}
}
else
@@ -5574,6 +5579,10 @@ bool FSlateApplication::RoutePointerMoveEvent(const FWidgetPath& WidgetsUnderPoi
LOG_EVENT( IsDragDropping() ? EEventLog::DragOver : EEventLog::MouseMove, Reply )
bHandled = Reply.IsEventHandled();
+ if (bHandled)
+ {
+ CurrentWidgetsUnderCursor = WidgetsUnderPointer.GetPathDownTo(Reply.GetHandler().ToSharedRef());
+ }
}
// Give the current drag drop operation a chance to do something
@@ -5590,14 +5599,14 @@ bool FSlateApplication::RoutePointerMoveEvent(const FWidgetPath& WidgetsUnderPoi
DragDropContent->SetCursorOverride(EMouseCursor::None);
}
#endif
- FScopedSwitchWorldHack SwitchWorld( WidgetsUnderPointer );
+ FScopedSwitchWorldHack SwitchWorld(CurrentWidgetsUnderCursor);
DragDropContent->OnDragged( DragDropEvent );
// Update the window we're under for rendering the drag drop operation if
// it's a windowless drag drop operation.
- if ( WidgetsUnderPointer.IsValid() )
+ if (CurrentWidgetsUnderCursor.IsValid() )
{
- DragDropWindowPtr = WidgetsUnderPointer.GetWindow();
+ DragDropWindowPtr = CurrentWidgetsUnderCursor.GetWindow();
}
else
{
@@ -5622,7 +5631,7 @@ bool FSlateApplication::RoutePointerMoveEvent(const FWidgetPath& WidgetsUnderPoi
DragDropWindowPtr = nullptr;
}
- WidgetsUnderCursorLastEvent.Add(FUserAndPointer(PointerEvent.GetUserIndex(), PointerEvent.GetPointerIndex()), FWeakWidgetPath(WidgetsUnderPointer));
+ WidgetsUnderCursorLastEvent.Add(FUserAndPointer(PointerEvent.GetUserIndex(), PointerEvent.GetPointerIndex()), FWeakWidgetPath(CurrentWidgetsUnderCursor));
PointerIndexLastPositionMap.Add(FUserAndPointer(PointerEvent.GetUserIndex(), PointerEvent.GetPointerIndex()), PointerEvent.GetScreenSpacePosition());
return bHandled;
diff --git a/Engine/Source/Runtime/Slate/Private/Widgets/Input/SButton.cpp b/Engine/Source/Runtime/Slate/Private/Widgets/Input/SButton.cpp
index e25f133..8c0c6ab 100644
--- a/Engine/Source/Runtime/Slate/Private/Widgets/Input/SButton.cpp
+++ b/Engine/Source/Runtime/Slate/Private/Widgets/Input/SButton.cpp
@@ -312,7 +312,7 @@ FReply SButton::OnMouseMove( const FGeometry& MyGeometry, const FPointerEvent& M
Release();
}
- return FReply::Unhandled();
+ return FReply::Handled();
}
void SButton::OnMouseEnter( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent )
As always, please let us know if you find any problems.