I have this method that loads a number of icons from a path, I want to be able to call it multiple time just to get a single icons, but I don’t want to do the entire process of creating a library and loading it every time. How to load everything just once?
UTexture2D* UUtils::GetSpellIconByName(FString AssetName)
{
auto textureLibrary = UObjectLibrary::CreateLibrary(UTexture2D::StaticClass(), true, GIsEditor);
FString textPath = "/Game/SpellCasterComponent/Icons/SpellButtonIcons";
textureLibrary->LoadAssetDataFromPath(textPath);
TArray<FAssetData> Assets;
textureLibrary->GetAssetDataList(Assets);
for (auto& asset : Assets) {
if (asset.AssetName.ToString() == AssetName)
{
UTexture2D* found = Cast<UTexture2D>(asset.GetAsset());
if (found)
{
return found;
}
}
}
return nullptr;
}
I don’t have much knowledge about the static keyword, but I THINK that you cannot do that. As far as I know the static keyword means that the function can be used without having an instance of the class it belongs to. Because of this I don’t think it is possible to do what you want because you’d have to give a value to that variable before being able to use it (if not you would get a runtime error) and if you don’t need to instance the class to use the function there isn’t anywhere for you to give a value to this variable because you wouldn’t run any code before calling the function (and I think that you can’t even use an outside variable inside a static function, MAYBE a const variable). Also, if there isn’t an instance of the class then it isn’t in memory, neither the variable is. Sorry if this explanation is confusing, couldn’t find a better way to explain it. Also, I MIGHT BE WRONG (probably). I just think that it is logical that it wont work (with the knowledge I currently have about it). Hope to have helped, at least a little bit.
I think that I need to save the textureLibrary variable in gamemode or something like that, and load it once in a beginplay method. But i’m not really sure what is the proper way of doing that.
Even if you save it in a game mode class you’ll still need a reference to it so you would need to pass a pointer of the game mode class every time you call this method. To do this just create a class that extends the game mode class and create a variable inside it to store the textures, then load the assets on the begin play of the class. Create a blueprint derived from that class you just
created and then set it as the default game mode on the world settings.
As a bonus, to avoid passing references around, you could have a static TWeakObjectPtr that is visible from where your static method is, and initialize it on GameMode::BeginPlay with the object library created in your game mode. That way you don’t need to pass the GameMode reference around (for safety, remember to check that the TWeakObjectPtr is Valid before accessing).
“you can’t even use an outside variable inside a static function”: yes, you can as long as the variable is in global scope (not part of a non-static object).