Download

Textures not visible when packaged but visible in PIE

Hello All.

Textures for Achievements, or Level Icon textures don’t load properly when the game is packaged for Windows but do work when testing with PIE. These textures are “dynamically” loaded using the following code:



UTexture2D* UMyGameInstance::LoadTexture(TAssetPtr<UTexture2D> Asset)
{
    if (Asset.IsPending())
    {
        const FStringAssetReference& AssetRef = Asset.ToStringReference();
        Asset = Cast<UTexture2D>(AssetLoader.SynchronousLoad(AssetRef));
    }

    return Asset.Get();
}


void UMyGameInstance::LoadAchievementTextures()
{
    LoadTexture(Achievement1);
    LoadTexture(Achievement2);
    LoadTexture(Achievement3);
    :
    :
}


These textures are not a power of two as they are UI textures. Do they need to be converted to ^2? Anything else I can do to get the textures to load properly?

Thank you.

EDIT [2015.10.15.12:12:00]

I now know it has nothing to do with power of 2 textures. It may be more to do with the garbage collector more than anything else. I managed to get the textures loaded, and visible in the UI. However, after coming back from gameplay the textures are white again.

It appears to be with TAssetPtr usage. Possibly I’m not using it correctly. Two major changes that I made were to switch from initialing loading the textures to loading them on each call. That is, when a specific texture is requested to call my LoadTexture function:



UTexture2D* UMyGameInstance::LoadTexture(TAssetPtr<UTexture2D> Asset)
{
    if (Asset.IsPending() || !Asset.IsValid())
    {
        const FStringAssetReference& AssetRef = Asset.ToStringReference();
        Asset = Cast<UTexture2D>(AssetLoader.SynchronousLoad(AssetRef));
    }

    return Asset.Get();
}


Upon initial startup this works fine. However, stating the game and returning back to the menu causes the game to crash. Should the code be reworked to:



UTexture2D* UMyGameInstance::LoadTexture(TAssetPtr<UTexture2D> Asset)
{
    if(!Asset.IsPending() && !Asset.IsValid())
    {
        Asset.Reset();
    }

    if (Asset.IsPending() || !Asset.IsValid())
    {
        const FStringAssetReference& AssetRef = Asset.ToStringReference();
        Asset = Cast<UTexture2D>(AssetLoader.SynchronousLoad(AssetRef));
    }

    return Asset.Get();
}


This works:



UTexture2D* UMyGameInstance::LoadTexture(TAssetPtr<UTexture2D> Asset)
{
    return Asset.LoadSynchronous();
}


So instead of using FStreamableManager, TAssetPtr::LoadSynchronous works the best. Actually, it appears to work really well.

And if you’re inclined to read up on loading assets, I’d like to suggest the following:

And what has become my personal favorite: