却写杂布计 发表于 2020-12-24 09:36

Unreal编辑器拓展_Gizmo

Unity的编辑器拓展十分方便,只要重写OnDrawGizmos()就能实现编辑器下的可视化,而虚幻并没有对应的功能。不过虚幻编辑器的拓展也是很强大的,只要几步也能写个接口提供Gizmo的绘制。
创建编辑器模式插件。
重写你的FEdMode子类
bool IsCompatibleWith(FEditorModeID OtherModeID) const override返回true。
bool UsesToolkits() const override返回false。
可以删除你的Toolkit类型及清空依赖,不需要模式面板。
声明EdMode的ID
const static FEditorModeID EM_XD_DrawGizmoEdModeId;
const FEditorModeID FXD_DrawGizmoEdMode::EM_XD_DrawGizmoEdModeId = TEXT("EM_XD_DrawGizmoEdMode");

进入你的IModuleInterface子类
在StartupModule()的实现后面补上
FEditorModeRegistry::Get().RegisterMode<FXD_DrawGizmoEdMode>(FXD_DrawGizmoEdMode::EM_XD_DrawGizmoEdModeId);       
FCoreDelegates::OnPostEngineInit.AddLambda([]()
        {
                GLevelEditorModeTools().AddDefaultMode(FXD_DrawGizmoEdMode::EM_XD_DrawGizmoEdModeId);
        });在ShutdownModule()中补上
FCoreDelegates::OnPostEngineInit.RemoveAll(this);
FEditorModeRegistry::Get().UnregisterMode(FXD_DrawGizmoEdMode::EM_XD_DrawGizmoEdModeId);

至此准备工作结束,可以进行Gizmo绘制的实现。
新建运行时模块DrawGizmoRuntime(名字随意),创建接口DrawGizmoInterface,并提供以下函数定义。(模块创建方式可以参考https://wiki.unrealengine.com/Creating_an_Editor_Module)
virtual void DrawGizmoNative(const FSceneView* View, FViewport* Viewport, FPrimitiveDrawInterface* PDI, bool IsSelected) {}
virtual void DrawHUDNative(FViewport* Viewport, const FSceneView* View, FCanvas* Canvas, bool IsSelected) {}

再次进入你的FEdMode子类,重写
void Render(const FSceneView* View, FViewport* Viewport, FPrimitiveDrawInterface* PDI) override
{
        UWorld* World = GetWorld();
        for (TActorIterator<AActor> It(World); It; ++It)
        {
                AActor* Actor = *It;
                if (IXD_DrawGizmoInterface* DrawGizmo = Cast<IXD_DrawGizmoInterface>(Actor))
                {
                        DrawGizmo->DrawGizmoNative(View, Viewport, PDI, Actor->IsSelectedInEditor());
                }
        }
}

void DrawHUD(FEditorViewportClient* ViewportClient, FViewport* Viewport, const FSceneView* View, FCanvas* Canvas) overrid
{
        UWorld* World = GetWorld();
        for (TActorIterator<AActor> It(World); It; ++It)
        {
                AActor* Actor = *It;
                if (IXD_DrawGizmoInterface* DrawGizmo = Cast<IXD_DrawGizmoInterface>(Actor))
                {
                        DrawGizmo->DrawHUDNative(Viewport, View, Canvas, Actor->IsSelectedInEditor());
                }
        }
}

向全场景的Actor广播绘制事件。


如何使用:
继承DrawGizmoInterface,重写提供的DrawGizmoNative与DrawHUDNative。
例子:
{
        DrawDirectionalArrow(PDI, (InteractSingleConfig.InteractLocation * GetActorTransform()).ToMatrixWithScale(), FColor::Red, 50.f, 5.f, SDPG_World, 1.f);
}具体参考PrimitiveDrawingUtils类,有详细的绘制帮助函数。


如何接收点击事件?
参考FSplineComponentVisualizer类吧。


TODO:
提供蓝图绘制版本。在编辑的红框标识区域添加可见性开关。


Github地址:
页: [1]
查看完整版本: Unreal编辑器拓展_Gizmo