3.2 关卡编辑器模式(EdMode):场景交互工具
EdMode 的定位
需要「在视口里点击、拖拽、框选,配合自定义渲染」,就要 EdMode——「关卡编辑器模式」(https://www.wanxiangyundang.top/read/unreal-engine-5-8-docs/level-editor-modes-in-unreal-e-4b5a)。官方的建模工具、笔刷、PCG 编辑器、样条工具都是它。EdMode 给你三个能力:
- 模式工具栏 UI(左侧 Modes 面板里出现你的工具)
- 输入捕获:鼠标点击/移动/键盘事件
- 视口绘制:HUD、提示线、gizmo
最小骨架
// ① 模式类
class FMyEditorMode : public FEdMode
{
virtual void Enter() override; // 进入模式(显示 UI、初始化状态)
virtual void Exit() override; // 退出(清理)
virtual bool InputKey(...) override; // 鼠标/键盘事件
virtual void Render(const FSceneView* View, FViewport* Viewport, FPrimitiveDrawInterface* PDI) override; // 视口绘制
};
注册(模块 StartupModule):
FEditorModeRegistry::Get().RegisterMode<FMyEditorMode>(
FMyEditorMode::EM_MyMode, FText::FromString("我的工具"),
FSlateIcon(), true);
常用交互:鼠标点击选点
bool FMyEditorMode::InputKey(FEditorViewportClient* ViewportClient, FViewport* Viewport, FKey Key, EInputEvent Event)
{
if (Key == EKeys::LeftMouseButton && Event == IE_Pressed)
{
// 屏幕坐标 → 世界射线
FSceneView View = ...;
FViewportCursorLocation CursorLoc = ViewportClient->GetCursorWorldLocation(...);
FVector Origin = CursorLoc.GetOrigin(), Dir = CursorLoc.GetDirection();
// 射线检测
FHitResult Hit;
GetWorld()->LineTraceSingleByChannel(Hit, Origin, Origin + Dir * 10000, ECC_Visibility);
if (Hit.bBlockingHit) { PlaceSomethingAt(Hit.Location); }
return true; // 事件已被消费
}
return false;
}
视口绘制
void FMyEditorMode::Render(const FSceneView* View, FViewport* Viewport, FPrimitiveDrawInterface* PDI)
{
// 画点、线、网格、辅助提示
PDI->DrawLine(Start, End, FLinearColor::Green, SDPG_World);
PDI->DrawPoint(Point, FLinearColor::Red, 10.0f, SDPG_World);
}
配合HUD 文本(HUDCanvas / ULineBatchComponent)显示操作提示。工具的可用性一半在「视口里告诉用户当前在做什么」。
EdMode Toolkit(UI)
EdMode 可带 Toolkit(Slate 面板,显示在 Modes 面板里):
class FMyEditorModeToolkit : public FModeToolkit
{
virtual TSharedPtr<SWidget> GetInlineWidget() override; // 返回你的 Slate UI
};
典型结构:上方参数(半径、数量)+ 下方说明。参数变更通过 Toolkit 通知 Mode。
EdMode 的坑
- 生命周期:Mode 在进入/退出时反复创建销毁,别持有外部对象引用不清理
- 与默认选择的冲突:消费了事件返回 true,不消费返回 false——返回 true 会让「左键选择 Actor」失效,想保留选择行为要小心
- 多视口:每个视口独立调用 Render/InputKey,状态别假设单视口
- 撤销:EdMode 的场景修改同样要走 FScopedTransaction,否则不可撤销
- 性能:Render 每帧调用,重计算缓存住
什么时候别用 EdMode
如果工具只是「点了按钮批量处理场景里的 Actor」——不需要视口交互,普通菜单命令 + EUW 就够了。EdMode 的复杂度不值得。一个判断标准:用户要不要「看着视口、指着场景里的东西」操作。要 → EdMode;不要 → 其他方式。
延伸
- 想做严肃的几何工具(布尔、推拉),看「几何体脚本用户指南」(https://www.wanxiangyundang.top/read/unreal-engine-5-8-docs/geometry-scripting-users-guide-7bb8)
- UE5 的建模模式本身就是 EdMode 的最佳示例——反射器 + 源码可读
心得:EdMode 工具的体验有三个层次:① 准(射线检测精确)② 看得见(视口提示到位)③ 可撤销。做到① 的工具能演示,做到②③ 的工具才敢给别人用。我们做场景笔刷工具时,60% 时间花在视口提示和撤销上,而不是功能本身。
