原始代码
首先,让我们看看原始代码片段:
cpp
// Some widgets might want to provide an alternative Tooltip Handler.
if (bCanSpawnNewTooltip || !NewTooltip)
{
TSharedPtr<SWidget> NewTooltipWidget = NewTooltip ? NewTooltip->AsWidget() : TSharedPtr<SWidget>();
for (int32 WidgetIndex = WidgetsToQueryForTooltip.Widgets.Num() - 1; WidgetIndex >= 0; --WidgetIndex)
{
const TSharedRef<SWidget>& CurWidget = WidgetsToQueryForTooltip.Widgets[WidgetIndex].Widget;
if (CurWidget->OnVisualizeTooltip(NewTooltipWidget))
{
// Someone is taking care of visualizing this tooltip
NewTooltipVisualizer = CurWidget;
break;
}
}
}
修改后的代码
现在,我们来看一下修改后的版本:
cpp
// Some widgets might want to provide an alternative Tooltip Handler.
if (bCanSpawnNewTooltip || !NewTooltip)
{
TSharedPtr<SWidget> NewTooltipWidget = NewTooltip ? NewTooltip->AsWidget() : TSharedPtr<SWidget>();
#if (UE_BUILD_SHIPPING || UE_BUILD_DEBUG)
FVector2D WindowInitialDesiredSize = SlateApp.GetTopLevelWindows()[0]->GetInitialDesiredSizeInScreen();
FVector2D ViewportSize = SlateApp.GetTopLevelWindows()[0]->GetViewport()->GetSize();
FWidgetPath WidgetsUnderCursor = SlateApp.LocateWindowUnderMouse(FVector2D (ViewportSize.X-170,63), SlateApp.GetInteractiveTopLevelWindows(), /*bIgnoreEnabledStatus =*/true, UserIndex);
for (int32 WidgetIndex = WidgetsUnderCursor.Widgets.Num() - 1; WidgetIndex >= 0; --WidgetIndex)
{
const TSharedRef<SWidget>& CurWidget = WidgetsUnderCursor.Widgets[WidgetIndex].Widget;
if (CurWidget->OnVisualizeTooltip(NewTooltipWidget))
{
// Someone is taking care of visualizing this tooltip
NewTooltipVisualizer = CurWidget;
break;
}
}
#else
for (int32 WidgetIndex = WidgetsToQueryForTooltip.Widgets.Num() - 1; WidgetIndex >= 0; --WidgetIndex)
{
const TSharedRef<SWidget>& CurWidget = WidgetsToQueryForTooltip.Widgets[WidgetIndex].Widget;
if (CurWidget->OnVisualizeTooltip(NewTooltipWidget))
{
// Someone is taking care of visualizing this tooltip
NewTooltipVisualizer = CurWidget;
break;
}
}
#endif
}
主要原因
主要看当前的要显示ToolTip的区域是否有一个SVirtualWindow,如果有就将ToolTip显示在SVirtualWindow之内就行,否则的话NewTooltipVisualizer将不会赋值,导致的后果就是他会新生成一个SWindow,独立于Pixelstreaming的TargetWindow,而Pixelstreaming只捕获TargetWindow画面,所以导致看到的画面中没有ToolTip并且伴随着闪烁,如果显卡能力稍弱一点可能会导致崩溃
解决的办法
就是将调用显示ToolTip的逻辑中插入每次都检测一个固定位置,这个固定位置是一定包含SVirtualWindow的就行(比如我就是将WidgetsToQueryForTooltip替换为了我自己通过位置检测的位置获得的FWidgetPath,这个位置是在Viewport中放置的一个按钮)