How do I display UTexture2D on UImage?

I want to display UTexture2D on UImage widget.But after I will Utexture2d set into UImage Brush, call SetVisibility (ESlateVisibility: : Visible) to display the userwidget causes a crash.
Here is my code:

UCLASS()
class RG_UNREAL_API UMyUserInterface : public UUserWidget
{
GENERATED_BODY()
UPROPERTY()
class UTexture2D* m_pMainTexture;
UPROPERTY()
class UImage* m_pMainImage;

// This function is called in the blueprint when it is construct.
UFUNCTION(BlueprintCallable)
void InitVideoReplay(int nCamRes, int nCamNum);

// This function is called when a button  in another interface is clicked.
UFUNCTION(BlueprintCallable)
void ShowMyUMG();
}

void URGVideoReplay::InitVideoReplay(int nCamRes, int nCamNum)
{
m_pMainImage= Cast<URgVideoImage>(GetWidgetFromName(TEXT("Main_Image")));
m_pMainTexture= UTexture2D::CreateTransient(640, 480);
if (m_pMainImage!= nullptr && m_pMainTexture!= nullptr)
{
    m_pMainImage->Brush.SetResourceObject(m_pMainTexture);
}
}

void URGVideoReplay::ShowMyUMG()
{
//The program will crash after the following code is executed. I checked that m_pMainTexture is not NULL and is still a valid object.
SetVisibility (ESlateVisibility: : Visible); 
}

Since no one has answered, I’ll take a shot though I’ve not directly referenced a UMG in this manner from C++. I use BP UMGs parented to a C++ parent that makes variables accessible to the BP child and let the BP do the settings via events. Just saying, my advice is probably not valuable.

SetVisibility stands without a pointer to m_pMainImage so you are attempting to set visibility on the entire UMG Class (which I’m not versed in why such a thing would be done). If that is your intent, then my comment is useless. But if you are attempting to set the visibility of the image, it would seem you should have a pointer to that image widget on that statement. Possibly something like

m_pMainImage->SetVisibility(ESlateVisibility::Visible);

  • m_pMainImage is valid. I got the instantiated object of the blueprint through the m_pMainImage= Cast(GetWidgetFromName(TEXT(“Main_Image”)));

The normal call to SetVisibility will not crash when I do not execute m_pMainImage->Brush.SetResourceObject(m_pMainTexture);

Sorry, I thought you said in the comment that it crashes when it reaches SetVisibility. And SetVisibility is pointed to by “this” which would be the UUserWidget (or the whole class rather than a specific widget). I’m sure that’s fine if you say, I just didn’t understand why you would want to do a call to this->SetVisibility when it seemed you were interested in m_pMainImage->SetVisibility (turning the graphic on and off). I guess I don’t understand what you are trying to do. Possibly someone else will respond who gets it. As I said, I leave the toggling of individual widgets to the BP child of the C++ UUserWidget class so I do things a different way. Sorry again.

Edit: I’ll wait till I see you’ve seen my post and delete my responses so you can get the post count back to 0. Seems like it’s more likely someone else will respond if you’ve had no replies in the post count. Let me know.

I’ll be honest: I have no idea what’s going on in your code, and I won’t try to interpret it, but I’ll try to help you do what you’re intending to do with it.

Try something like this:

UCLASS()
class MYGAME_API UMyWidget : public UUserWidget
{
    GENERATED_BODY()

public:

    UPROPERTY(meta = (BindWidget))
    class UImage* MainImage;

    virtual void NativeOnInitialized() override;

    UFUNCTION(BlueprintCallable)
    void ShowMyUMG();
}
void UMyWidget::NativeOnInitialized()
{
    MainImage->SetBrushFromTexture(UTexture2D::CreateTransient(640, 480));
    MainImage->SetVisibility(ESlateVisibility::Hidden);
}

void UMyWidget::ShowMyUMG()
{
    MainImage->SetVisibility(ESlateVisibility::Visible);
}

Let me know if this works.

Edit: Small note, your UImage needs to be named “MainImage” to bind properly to the variable.

Since this image is a part of the entire UMG interface, I want to display the entire control containing Image, I have found the reason, thank you for your reply!

Thanks for your reply! I have found the reason, and I will reply the reason below!

Thank you for all the responses. I found the reason for the issue. All my pointers were valid, so the crash was not caused by a null pointer. I discovered that after calling UTexture2D::CreateTransient(640, 480); , followed by UTexture2D::UpdateResource(); , and then displaying the UMG interface, it no longer caused a crash. Additionally, the crash’s pdb location was in SlateRHI. I didn’t delve into the engine’s source code in detail, but I suspect that after calling CreateTransient , the content in the UTexture2D used for rendering to the interface might have been empty and needed to be updated using UpdateResource . I didn’t see anyone mentioning this anywhere, but fortunately, I was able to resolve it. Thanks for all your help!

Here is my modified code:

UCLASS()
class RG_UNREAL_API UMyUserInterface : public UUserWidget
{
GENERATED_BODY()
UPROPERTY()
class UTexture2D* m_pMainTexture;
UPROPERTY()
class UImage* m_pMainImage;

// This function is called in the blueprint when it is construct.
UFUNCTION(BlueprintCallable)
void InitVideoReplay(int nCamRes, int nCamNum);

// This function is called when a button  in another interface is clicked.
UFUNCTION(BlueprintCallable)
void ShowMyUMG();
}

void URGVideoReplay::InitVideoReplay(int nCamRes, int nCamNum)
{
m_pMainImage= Cast<URgVideoImage>(GetWidgetFromName(TEXT("Main_Image")));
m_pMainTexture= UTexture2D::CreateTransient(640, 480);
if (m_pMainImage!= nullptr && m_pMainTexture!= nullptr)
{
    m_pMainImage->Brush.SetResourceObject(m_pMainTexture);
    m_pMainTexture->UpdateResource();
}
}

void URGVideoReplay::ShowMyUMG()
{
SetVisibility (ESlateVisibility: : Visible); 
}




This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.