FindObject not working

I need to reference UMG blueprints at runtime (not in the constructor) to create it. While this code in the constructor works just fine:

TArray<FString> widgetPaths;
widgetPaths.Add(TEXT("/Game/SGUI/UMG/AllyDot.AllyDot_C"));
widgetPaths.Add(TEXT("/Game/SGUI/UMG/FloatingBar.FloatingBar_C"));
widgetPaths.Add(TEXT("/Game/SGUI/UMG/FloatingText.FloatingText_C"));
widgetPaths.Add(TEXT("/Game/SGUI/UMG/Inventory.Inventory_C"));
widgetPaths.Add(TEXT("/Game/SGUI/UMG/PlayerHP.PlayerHP_C"));

for (int i = 0; i < widgetPaths.Num(); i++)
{
	ConstructorHelpers::FObjectFinder<UClass> widgetClass(*widgetPaths[i]);
	if (widgetClass.Succeeded()) widgetClassesCache.AddUnique(widgetClass.Object);
}

When I try to use FindObject to do the same thing, but out of the constructor (calling it at BeginPlay and later):

    TArray<FString> widgetPaths;
    widgetPaths.Add(TEXT("/Game/SGUI/UMG/AllyDot.AllyDot_C"));
    widgetPaths.Add(TEXT("/Game/SGUI/UMG/FloatingBar.FloatingBar_C"));
    widgetPaths.Add(TEXT("/Game/SGUI/UMG/FloatingText.FloatingText_C"));
    widgetPaths.Add(TEXT("/Game/SGUI/UMG/Inventory.Inventory_C"));
    widgetPaths.Add(TEXT("/Game/SGUI/UMG/PlayerHP.PlayerHP_C"));
    
    for (int i = 0; i < widgetPaths.Num(); i++)
    {
    	auto widgetClass = FindObject<UClass>(ANY_PACKAGE, *widgetPaths[i]);
    	if (widgetClass) widgetClassesCache.AddUnique(widgetClass);
    }

It just returns nullptrs. Am I doing something wrong?

PS: I need to reference UMG blueprints after the initialization, so using ConstructorHelpers is not an option in this case.

Hi ,

I don’t have much context for some of the variables you’re using so I can’t go too in-depth while looking into this issue, but I can at least provide you with and idea of what the problem is. I believe the issue with your implementation of FindObject may be due to the parameters it is expecting.

Please go to the following link: FindObject | Unreal Engine Documentation

This page shows what the expected parameters are for the FindObject function, they are quite different from the ones for FObjectFinder. (FObjectFinder | Unreal Engine Documentation)

If this isn’t enough to help you overcome this issue, please supply me with the .cpp and .h that these functions are being used in to hopefully give me more context.

Have a nice day,

Hello ,

Thank you for the answer!

All the variables I’m using (except widgetClassesCache) are defined in the example code. As for widgetClassesCache — it’s just a static TArray.

I have already seen the docs for these methods, as well as some related questions and even skimmed through some uses in the engine sources, so I believe I’m passing the right parameters.

Here is the .h and .cpp files:

.com//SagaGUI/blob/master/Plugins/SGUI/Source/SGUI/Private/SagaWidget.h

.com//SagaGUI/blob/master/Plugins/SGUI/Source/SGUI/Private/SagaWidget.cpp

I will really appreciate if you’ll look at them, as I’m out of the ideas of what could be wrong.

Thank you very much for the help!

Hi

After digging into the use of FindObject itself, I believe I’ve found the problem. It seems that LoadObject must be used before using FindObject as it cannot locate a class that has not yet been loaded. FObjectFinder must automatically load classes or something of the sort so that it can bypass this for ease of access.

Below is a link for the LoadObject function itself.

If using that function doesn’t work out for you, please let me know, I’d be happy to look into the issue further with you.

Have a nice day,

1 Like

Yes, it works! I just used LoadObject instead of FindObject.
Thank you very much!

but findObject always fail even after a success call to LoadObject(), wouldn’t this trigger a disk I/O slowing the game?

Yes, I tested the same with this code:

UClass* animClass1 = FindObject<UAnimBlueprintGeneratedClass>(ClassPackage, TEXT("Rat_AnimBP.Rat_AnimBP_C"));
UClass* Result = LoadClass<UAnimInstance>(nullptr, TEXT("/Game/Npcs/rat/Rat_AnimBP.Rat_AnimBP_C"), nullptr, LOAD_None, nullptr);
UClass* animClass2 = FindObject<UAnimBlueprintGeneratedClass>(ClassPackage, TEXT("Rat_AnimBP.Rat_AnimBP_C"));

Note the first and thrid lines are identical. But the first line will return NULL, and the third will return the right value, so FindObject really works only if the object is already loaded.

In addition to that I checked the LoadObject code and it’s anyway doing a Find first to ensure its not loading twice.

1 Like