So for a menu I’m loading textures at runtime and putting them in buttons like so:
FReply SStandardSlateWidget::selectPuzzleCategory(int32 catSent) {
pickPuzzleScrollBox->ClearChildren();
UMyGameInstance* gameInstance = Cast<UMyGameInstance>(playerControllerReference->GetGameInstance());
for (int32 counter = 0; counter < gameInstance->puzzlesArray.Num(); counter++) {
if (gameInstance->puzzlesArray[counter].catNumber == catSent) {
ItemsToStream.AddUnique(gameInstance->puzzlesArray[counter].iconTextureRef.ToSoftObjectPath());
}
}
currentCatNum = catSent;
gameInstance->StreamableManager.RequestAsyncLoad(ItemsToStream, FStreamableDelegate::CreateRaw(this, &SStandardSlateWidget::OnLoadComplete));
return FReply::Handled();
}
void SStandardSlateWidget::OnLoadComplete() {
UKismetSystemLibrary::PrintString(GEngine->GetWorld(), "Load Complete ", true, true, FLinearColor(1.000000, 1.000000, 1.000000, 1.000000), 40.0);
UMyGameInstance* gameInstance = Cast<UMyGameInstance>(playerControllerReference->GetGameInstance());
for (int32 counter = 0; counter < gameInstance->puzzlesArray.Num(); counter++) {
if (gameInstance->puzzlesArray[counter].catNumber == currentCatNum) {
int32 currentTextureNumber = iconTextures.Emplace(Cast<UTexture2D>(gameInstance->puzzlesArray[counter].iconTextureRef.Get()));
iconTextures[currentTextureNumber]->AddToRoot();
}
}
for (int32 counter = 0; counter < iconTextures.Num(); counter++) {
if (iconTextures[counter]) {
//int32 currentBrushNumber = iconBrushes.AddDefaulted(1);
int32 currentBrushNumber = iconBrushes.Add(new FSlateBrush);
iconBrushes[currentBrushNumber]->SetResourceObject(iconTextures[counter]);
iconBrushes[currentBrushNumber]->ImageSize.X = iconTextures[counter]->GetSurfaceWidth();
iconBrushes[currentBrushNumber]->ImageSize.Y = iconTextures[counter]->GetSurfaceHeight();
iconBrushes[currentBrushNumber]->DrawAs = ESlateBrushDrawType::Image;
//UKismetSystemLibrary::PrintString(GEngine->GetWorld(), LexToString(currentBrushNumber)+" iconBrushes.GetRenderingResource().IsValid " + LexToString(iconBrushes[currentBrushNumber].GetRenderingResource().IsValid()), true, true, FLinearColor(1.000000, 1.000000, 1.000000, 1.000000), 40.0);
UKismetSystemLibrary::PrintString(GEngine->GetWorld(), "GetSurfaceWidth() " + LexToString(iconTextures[counter]->GetSurfaceWidth()) + " GetSurfaceHeight() " + LexToString(iconTextures[counter]->GetSurfaceHeight()), true, true, FLinearColor(1.000000, 1.000000, 1.000000, 1.000000), 40.0);
pickPuzzleScrollBox->AddSlot()
SNew(SHorizontalBox)
+ SHorizontalBox::Slot().AutoWidth().HAlign(HAlign_Left)
SNew(SButton)
.ButtonStyle(FCoreStyle::Get(), "NoBorder")
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
.ForegroundColor(FSlateColor::UseForeground())
TSharedRef<SImage>(SNew(SImage).Image(iconBrushes[currentBrushNumber]))
]
.TextStyle(&buttonFont).OnClicked_Raw(this, &SStandardSlateWidget::selectPuzzleCategory, counter).IsFocusable(false)
]
];
pickPuzzleScrollBox->AddSlot()
SNew(SHorizontalBox)
+ SHorizontalBox::Slot().AutoWidth().HAlign(HAlign_Left)[SNew(SSpacer).Size(FVector2D(10, 10))]
];
} else {
UKismetSystemLibrary::PrintString(GEngine->GetWorld(), "No Item Data ", true, true, FLinearColor(1.000000, 1.000000, 1.000000, 1.000000), 40.0);
}
if (counter >= 5) {
//break;
}
}
}
A ran into an issue where with 11 images loaded the first 4 were not displayed. If I tried to load just 4 they all showed up but as soon as I tried loading 5 the first 4 didn’t show (the button was still there with an image of width/height zero.
After looking into possible garbage collection of textures and stuff I finally found out it was the slate brush array.
Changing:
UPROPERTY() TArray<FSlateBrush> iconBrushes;
int32 currentBrushNumber = iconBrushes.AddDefaulted(1);
To:
UPROPERTY() TArray<FSlateBrush*> iconBrushes;
int32 currentBrushNumber = iconBrushes.Add(new FSlateBrush);
Did fix the problem, but I’m not sure why. Doesn’t AddDefaulted create a new one as well? I’m scared that I didn’t fix the problem but just changed the timing of things enough where it’s working…for now.