Download

[C++] Render on EDITOR viewports using Canvas (or alternatives).

Hi people! I’ve been trying to wrap my head around a problem for the past 3 days. I’m writing a new actor component which is basically a 2D capsule shape that lies on a 3D plane.

It needs a debug function where it will render on top of everything. I managed to get this working at runtime with HUD and Canvas by projecting it from world to screen and drawing it with Canvas primitives (triangles and lines), but I’m having problems to do so in the editor viewports, since it seems there’s no AHUD instances in editor. I tried the following in my ComponentTick method:



for(TObjectIterator<UCanvas> It; It; ++It)
{
    UCanvas* Canvas = *It;
    if(Canvas && Canvas->Canvas)
    {
        // Draw using Canvas->DrawItem()
    }
}


It works since it seems to find the UCanvas instance for each viewport’s UWorld, but it flickers and crashes the editor randomly.
Any idea how can I sync my component to the viewport draw? I accept other ideas on another way to render my component on top of the scene (I even tried reading PrimitiveComponent to see if I could understand how to create a SceneProxy for my component, so any guidance on that side could be super useful!)
Thanks in advance :slight_smile:

So after 4 more days of wandering around, I figured it out. I’m more or less going to explain how I solved it so anyone who stumble across this problem don’t have to rely on the community since this doesn’t seem to be a popular topic (yes, I was annoyed because this thread got no love, but I understand rendering is a hard topic on UE4).

I finally took the route of PrimitiveComponents. In my case, I created a new component child of UMeshComponent (for material setters/getters) and extended FPrimitiveSceneProxy to implement a FVertexFactory, FStaticMeshVertexBuffers, FDynamicMeshIndexBuffer32 and FMaterialRelevance, add them to a FMeshBatch/FMeshBatchElement and send them to the FMeshElementCollector that FPrimitiveSceneProxy::GetDynamicMeshElements() provides us with for each ***FSceneView ***(also provided). Then I overrode UMeshComponent::CreateSceneProxy() to return my custom FPrimitiveSceneProxy.

All the necessary information I took from ProceduralMeshComponent.cpp