Download

Loading Blueprints at runtime fails on launch or packaged

If i hit the play button in the editor, everything works just fine. FAssetRegistry finds and lets me load StaticMeshs, Materials and Blueprints without a problem.
But as soon as i launch the game or package and run the exe, the blueprints cannot be loaded anymore.

Asset discovery code still finds the blueprints:



	Filter.PackagePaths.Empty();
	Filter.PackagePaths.Add(FName("/Game/LevelCreator/Objects/Dimension1/Biome1/Lights"));
	MeshAssetList.Empty();
	AssetRegistryModule.Get().GetAssets(Filter, MeshAssetList);

And i load them with this:



template <typename ObjClass>
static FORCEINLINE ObjClass* LoadObjFromPath(const FName& Path)
{
	if (Path == NAME_None) return NULL;
	//~

	return Cast<ObjClass>(StaticLoadObject(ObjClass::StaticClass(), NULL, *Path.ToString()));
}

On launch i then get log entries like this:



[2015.04.11-15.32.47:804]  0]LogUObjectGlobals:Warning: Failed to find object 'Blueprint /Game/LevelCreator/Objects/Dimension1/Biome1/Lights/FluorescentBar.FluorescentBar'

I packaged the game without using pak files and checked, the file was where it should be.

All my blueprints are derived from Actor and have a static mesh and a point light in them.

Are blueprints not useable in packaged/launch mode via dynamic asset loading?

I really like the bp’s to create small assets which i (hopefully) can spawn at different locations.

UObjectLibrary

Have you checked out the UObjectLibrary class?!

It let’s you load blueprints!

UObjectLibrary



/** Load an entire subdirectory of blueprints into this object library. Only loads blueprints of passed in class. Returns number of assets loaded */
virtual int32 LoadBlueprintsFromPaths(const TArray<FString>& Paths);


:slight_smile:

Rama

Found the cause

Hi Rama

looking at its source it relies on EngineUtils::FindOrLoadAssetsByPath.

And now i know why it isnt working.

In Editor mode you can load blueprints with EngineUtils::FindOrLoadAssetsByPath(path, array, EngineUtils::ATL_Regular).

This does NOT work in launch mode.
You have to load the class (EngineUtils::ATL_Class)

This was really annoying and very time consuming.

**Reminder to EPIC: **At least put in some Warning in if a function behaves differently from edit mode. Then we can find the cause sooner.

But i got it running.


template <typename ObjClass>
static FORCEINLINE ObjClass* LoadBlueprintFromPath(const FName& Path, const FName& BlueprintName)
{
	if (Path == NAME_None) return NULL;
	FString cName = BlueprintName.ToString().Append(FString("_C"));
	TArray<UObject*> tempArray;
	if (EngineUtils::FindOrLoadAssetsByPath(*Path.ToString(), tempArray, EngineUtils::ATL_Class))
	{
		for (int i = 0; i < tempArray.Num(); ++i)
		{
			UObject* temp = tempArray*;
			if (temp == NULL || (!Cast<ObjClass>(temp)) || (temp->GetName().Compare(cName) != 0))
			{
				continue;
			}
			
			return Cast<ObjClass>(temp);
		}
	}

	return NULL;
}


It defies the template approach, since its always a UBlueprintGeneratedClass, i know.

With a LoadBlueprintFromPath<UBlueprintGeneratedClass>() you can then spawn them with a GWorld->SpawnActor().

Thanks Rama, you got me on the right track :cool: