hi, I’d like to load images/textures async, everything is being loaded correctly, I just don’t know how to cast the loaded UObject to UTexture2D so I can assign it to a FSlateBrush and then the slate brush to a UBorder
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "MyUserWidget.generated.h"
/**
*
*/
UCLASS(Blueprintable)
class YOURGAME_API UMyUserWidget : public UUserWidget
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadWrite, EditAnywhere)
TSoftObjectPtr<UTexture2D> TextureToLoad;
UFUNCTION(BlueprintCallable)
UTexture2D* LoadImage(bool& Loaded);
UPROPERTY(BlueprintReadWrite,editAnywhere, meta = (BindWidget))
class UImage* BorderPicture;
};
Don’t forget to create an image inside of the widget and call it BorderPicture
cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyUserWidget.h"
#include "Components/Image.h"
#include "Blueprint/WidgetBlueprintLibrary.h"
UTexture2D* UMyUserWidget::LoadImage(bool& Loaded)
{
Loaded = false;
UTexture2D* Texture = nullptr;
FSoftObjectPath AssetData = TextureToLoad.ToSoftObjectPath();
if (AssetData.IsValid()) {
Texture = Cast<UTexture2D>(AssetData.TryLoad());
Loaded = Texture != nullptr;
FSlateBrush brushEffect = UWidgetBlueprintLibrary::MakeBrushFromTexture(Cast<UTexture2D>(Texture));
if (BorderPicture != nullptr) {
BorderPicture->SetBrush(brushEffect);
}
}
return Texture;
}
Set TextureToLoad to the needed image & after construct call LoadImage to see the results.
Seems pretty similar looking at the engine code of CommonLazyImage.cpp. They seem to use weak pointers for the UCommonLazyImage just in case it gets garbage collected.
It might have some overhead when compared to the simpler code.
void UCommonLazyImage::SetBrushFromLazyDisplayAsset(const TSoftObjectPtr<UObject>& LazyObject, bool bMatchTextureSize)
{
if (!LazyObject.IsNull())
{
TWeakObjectPtr<UCommonLazyImage> WeakThis(this); // using weak ptr in case 'this' has gone out of scope by the time this lambda is called
RequestAsyncLoad(LazyObject,
[WeakThis, LazyObject, bMatchTextureSize]() {
if (UImage* StrongThis = WeakThis.Get())
{
ensureMsgf(LazyObject.Get(), TEXT("Failed to load %s"), *LazyObject.ToSoftObjectPath().ToString());
if (UTexture2D* AsTexture = Cast<UTexture2D>(LazyObject.Get()))
{
StrongThis->SetBrushFromTexture(AsTexture, bMatchTextureSize);
}
else if (UMaterialInterface* AsMaterial = Cast<UMaterialInterface>(LazyObject.Get()))
{
StrongThis->SetBrushFromMaterial(AsMaterial);
}
}
}
);
}
else
{
ShowDefaultImage();
}
}