UCanvasRenderTarget2D::CreateCanvasRenderTarget2D GetWorld is not valid, null pointer

I have a custom UObject in C++ that creates an UCanvasRenderTarget2D object by calling the following:

UCanvasRenderTarget2D::CreateCanvasRenderTarget2D(UCanvasRenderTarget2D::StaticClass(), Width, Height);

This function gets down into the new object’s UCanvasRenderTarget2D::UpdateResource() function where it calls:

FCanvas RenderCanvas(GameThread_GetRenderTargetResource(), nullptr, FApp::GetCurrentTime() - GStartTime, FApp::GetDeltaTime(), FApp::GetCurrentTime() - GStartTime, GetWorld()->FeatureLevel);

The problem is that GetWorld() returns null and this object can never get created from within our custom UObject class. The comment on the FCanvas constructor states the following: “”

/** 
* Constructor. For situations where a world is not available, but time information is
*/
ENGINE_API FCanvas(FRenderTarget* InRenderTarget, FHitProxyConsumer* InHitProxyConsumer, float InRealTime, float InWorldTime, float InWorldDeltaTime, ERHIFeatureLevel::Type InFeatureLevel);

Is it expected that the GetWorld() function call should be valid at this point after calling the CreateCanvasRenderTarget2D function? If so, how can I ensure it is valid. I’m filing this under Bug Report because I think it is a bug. The world cannot be valid if the object was just created.

Any insight would be greatly appreciated.
Thanks,

Did you trace the code down? As I stated in the original post:

This function gets down into the new object’s UCanvasRenderTarget2D::UpdateResource() function where it calls:

FCanvas RenderCanvas(GameThread_GetRenderTargetResource(), nullptr, FApp::GetCurrentTime() - GStartTime, FApp::GetDeltaTime(), FApp::GetCurrentTime() - GStartTime, GetWorld()->FeatureLevel);

I don’t have access to the code from my current location but I recall it called the UpdateResource function in the create and that calls GetWorld().

Hey -

I was able to locate the CreateCanvasRenderTarget2D function in the source code for 4.6.1, however there is no call to UpdateResources in that function. Which version of the engine are you working in and at what point are you calling UpdateResources? If you could post a code snippet from your UObject to show how it is created and updated it will help us follow what is happening and when it is trying to access GetWorld.

Cheers

After checking the CanvasRenderTarget2D.cpp source file in 4.6.1, it doesn’t appear that UpdateResource is called in the CreateCanvasRenderTarget2D() function. Which version of the engine are you working in? Would it be possible to post the code from your UObject that creates the UCanvasRenderTarget2D?

Here is the full tree:
UCanvasRenderTarget2D::CreateCanvasRenderTarget2D calls NewCanvasRenderTarget->InitAutoFormat(Width, Height);

UTextureRenderTarget2D::InitAutoFormat calls UpdateResource();

UCanvasRenderTarget2D::UpdateResource() calls FCanvas RenderCanvas(GameThread_GetRenderTargetResource(), nullptr, FApp::GetCurrentTime() - GStartTime, FApp::GetDeltaTime(), FApp::GetCurrentTime() - GStartTime, GetWorld()->FeatureLevel);

GetWorld() returns NULL.

I have since utilized a different solution for my canvas that does not rely on this class because of this problem.

Hey -

When are you making the call to UCanvasRenderTarget2D::CreateCanvasRenderTarget2D? If the call is made on BeginPlay then it may be possible that the call to GetWorld is being made before the level has been created.

So how do you address this comment on that constructor as noted in my original post? Either the constructor shall not call GetWorld() or the comment of this constructor needs to be fixed. Regardless, one or the other is incorrect and I think the call to GetWorld() is incorrect because it is just getting the RHI info.

"/**

  • Constructor. For situations where a world is not available, but time information is
    */"

Hey -

How are you making the call to CreateCanvasRenderTarget2D()? There was a similar report of the blueprint version of that method causing a crash that I found is fixed in the 4.7 preview that is available through the launcher. Could you check if you’re able to use the method in 4.7 or lay out the steps for how you’re using it so that I can test on my end?

Thanks

Hi , thanks for the help but I’m sorry to say that I will not have the time to create a project to demonstrate this issue for you. I can explain what I was doing but I can’t do anymore than that. I ended up finding a different way to solve my problem that actually works better by tweaking the material parameters. So what I had was a HUD class that is composed of many HUD “widgets”. One of these HUD widgets was a compass but the HUD widgets are not actors they are components. I was creating the canvas render target from within this component. Because it is not an AActor, it does not have access to a valid UWorld object.

I have instead put a parameter into the material and I do the calculations from within the material rather than doing them in C++ on a canvas.

I submitted this bug report as an FYI that someone should fix that because the constructor even says that you can call this without a valid UWorld but if you do it crashes because it is expecting to have a valid UWorld object. I’m sorry but I’m very busy to contribute anymore to this bug report as I submitted it for informational purposes only. Someone should either not have it call GetWorld() or they should change the constructor’s comment.

I have many things on my plate right now and, sad to say, this is very very low priority for me.
Thanks again,

Hey -

Thanks for your report. I’ve tested this in 4.7 and it appears to be fixed. If you run into this problem again after 4.7 please let us know and we will investigate this bug further.

Cheers