Why static_cast worked, but Cast not?

Hi! I am assigning UTextureRenderTarget2D to image umg widget:


UTexture* ut = static_cast<UTexture*>(ArrayWithUTextureRenderTarget2D[s]);
Texture2D* ut2 = static_cast<UTexture2D*>(ut);
faceImage->SetBrushFromTexture(ut2);


And it works;

While, in this case:


UTexture* ut = Cast<UTexture>(ArrayWithUTextureRenderTarget2D[s]);
Texture2D* ut2 = Cast<UTexture2D>(ut);
faceImage->SetBrushFromTexture(ut2);


ut2 ends up being nullptr; Why it that so? I always had impression, that Cast is more advanced then static_cast

This isn’t going to answer your question. Need to know what type is stored in your array, the actual object type, so if it was casted before storing it in the Array, and also what is the runtime behavior, when you say it works do you mean it compiles or that it works at runtime and renders appropriately.

static_cast is meant to be used to undo an implicit conversion. Such as if your Array ArrayWithUTextureRenderTarget2D held type *void, so void pointers. The static cast would be correct to cast it back to it’s actual type. static_cast is not correct if you had stored the objects as their base type, it is not to be used for polymorphic objects, so if UTexture2D is a child class of UTexture then static_cast should not be used.

Inside ArrayWithUTextureRenderTarget2D are UTextureRenderTarget2D objects, which I directly dragged-and-dropped from inside Editor. When I say it works, that means, that I compile application, run it, and can see UTextureRenderTarget2D texture object being properly rendered inside UMG Image Widget, which I assign using SetBrushFromTexture;

Thank you for the reply, I’ll try to read second part several times, and hopefully understand it fully.

I would think dynamic_cast was the correct C++ cast because they are polymorphic objects.

Cast, should choose that one.

It doesn’t work because a UTextureRenderTarget2D object is not and can never be a UTexture2D. They both share UTexture as a base, but you can’t cast up to a base, then down to something else, it just doesn’t make sense.
The fact that it compiles with static_cast doesn’t mean it works. static_cast simply doesn’t check runtime types, so you’ll end up with a typed pointer to an object, which isn’t actually of that type. In other words, undefined behaviour. If your program didn’t crash, it’s only by pure chance.

Also, it’s not true that static_cast shouldn’t be used to cast from base to child. That’s a downcast, which is probably the number one use of static_cast. The point is you simply need to know for sure that the pointed to object will always be of the child type.

Hmmm, this is more serious, then I thought. Inside Editor, I can drag and drop it inside umg widget brush texture slot. Does that mean, that somewhere transparently in-editor, new UTexture2D object is being created, but not static or dynamic cast (as I originally suggested, as I simply drag-drop it inside editor)?

The resource property within a slate brush (which is what is exposed on UMG widgets) is marked as follows:


AllowedClasses="Texture,MaterialInterface,SlateTextureAtlasInterface"

So that suggests it probably just references the render target directly, since it derives from UTexture.

It looks like the method for UImage is more restrictive, requiring a UTexture2D. I’d imagine you can probably just use the SetBrush method instead, creating an FSlateBrush and passing your render target in as the InObjectResource parameter.

Ah, I see now! So this all about the method. Totally makes sense. Thank you! I’ve learned a lot from all this.