VR 世界空间 UI 的鼠标调试点击(WidgetInteraction)
PC 调试 VR 项目时,用鼠标点击世界空间 UMG(菜单/社交面板)的完整实现与陷阱。适用于 <Project> 及同类 VR pawn 项目(WidgetInteraction 挂在手柄上,InteractionSource=World)。
硬性机制(引擎源码实证,UE 5.6)
SetCustomHitResult()只在InteractionSource == EWidgetInteractionSource::Custom时被消费——WidgetInteractionComponent.cpp的 trace switch 里只有 Custom 分支读取 CustomHitResult;World 模式下注入完全无效,且无任何报错。PressPointerKey()在LastWidgetPath无效时会即时调DetermineWidgetUnderPointer()——无需等 Tick 注册 hover,同帧 SetCustomHitResult + Press 可行。PressAndReleaseKey()发送的是键盘按键事件(OnKeyDown/Up),按钮不视为点击;按钮点击必须走 pointer 语义(PressPointerKey/ReleasePointerKey,VR 扳机同款)。
正确实现模式
// 鼠标左键 handler(IA Boolean,IMC 映射 LeftMouseButton)
FVector Origin, Dir;
PC->DeprojectMousePositionToWorld(Origin, Dir);
FHitResult Hit;
GetWorld()->LineTraceSingleByChannel(Hit, Origin, Origin + Dir * 5000.f, ECC_GameTraceChannel1, Params); // 与项目 WidgetInteraction 同通道
if (Cast<UWidgetComponent>(Hit.GetComponent()))
{
WI->SetActive(true); // 可能被其他系统禁用
WI->InteractionSource = EWidgetInteractionSource::Custom; // 关键:Custom 才读 CustomHitResult
WI->SetCustomHitResult(Hit);
WI->PressPointerKey(EKeys::LeftMouseButton);
WI->ReleasePointerKey(EKeys::LeftMouseButton);
WI->InteractionSource = EWidgetInteractionSource::World; // 恢复 VR 手柄路径
}
三轮实证陷阱(按踩坑顺序)
PressAndReleaseKey→ 键盘事件,按钮无响应。PressPointerKey+SetCustomHitResult(World 模式)→ custom hit 被忽略,Press 回退用手柄自身射线打空。- 切 Custom 后生效;点完必须恢复 World,否则 VR 扳机点击失效。
辅助结论
- 射线通道必须与项目 WidgetInteraction 的 TraceChannel 一致(<Project> 用
ECC_GameTraceChannel1= "3DWidget")。 SetShowMouseCursor(true)只影响光标显示,不改变 GameOnly 输入路由,鼠标事件照常进 Enhanced Input。- 诊断:
UE_LOG打印hit=%d comp=%s——hit=0是射线/通道问题,hit=1无响应是 InteractionSource/语义问题。
Scan to join WeChat group