Download

Loading Blueprint From C++

I have a subsystem blueprint whose parent class in c++ is marked as abstract. The blueprint never loads automatically when I open the editor. The blueprint loads after double-clicking it. So how can I load the blueprint automatically without clicking on it? I was trying to just statically load the blueprint but it is not working.

FString spawnedBlueprintReference = TEXT("Blueprint'/MortarPlugin/MortarPlugin/Blueprints/BP_MortarResourceManager.BP_MortarResourceManager'");


		UObject* loadedObject = StaticLoadObject(UObject::StaticClass(), nullptr, *spawnedBlueprintReference);
		
		if(loadedObject)
		{ 
            //Getting Here
			UE_LOG(LogTemp, Warning, TEXT("Loading Blueprint subsystem SUCESS"));
		}
		else
		{
			UE_LOG(LogTemp, Warning, TEXT("Loading Blueprint subsystem NO SUCESS"));
		}

But this doesn’t load the blueprint. How can I load it ?

Bump any help :frowning:

Build.CS:

PublicDependencyModuleNames.AddRange(
	new string[] {
		"Core",
		"Json",
		"Engine",
		"CoreUObject",

		"AssetRegistry"
	}
);

Somewhere.H

#include "AssetRegistryModule.h"

Somewhere.CPP

void MyBase::LoadStuff()
{
	TArray<FAssetData>AssetData;

	const FAssetRegistryModule & AssetRegistry =
	FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");

	AssetRegistry.Get().GetAssetsByClass( TEXT("MyBaseClass_NAME") , AssetData );



	// check if valid:
	for (const auto & Data : AssetData)
	{
		if (Data.AssetName.ToString().Equals( TEXT("MySubClassIneed") , ESearchCase::CaseSensitive) )
		{
			UBlueprint* BP = GetBlueprintFromCDO(Data.GetAsset());
			if (BP && BP->GeneratedClass.Get())
			{
				if(
					!BP->GeneratedClass.Get()->HasAnyClassFlags(CLASS_Deprecated|CLASS_Hidden)
				) {
					// UMyBaseType* CDO = GetCDOfromBlueprint<UMyBaseType>(BP);
					// I do stuff in CDO.. 'GetCDOxx' above doesn't exist in your copy of Unreal.
				}
				break;
			}
		}
	}
}


Now, what I actually do, but it’s optional… I create a custom UBlueprint class and a custom asset factory to create blueprints from this class:

UCLASS(BlueprintType)
class MYPROJECT_API UMyCoreSystemBlueprint : public UBlueprint
{
	GENERATED_UCLASS_BODY()

#if WITH_EDITOR

	virtual bool SupportedByDefaultBlueprintFactory() const override
	{
		return false;
	}

#endif
};

I will not get into details of how to create asset factory, I talk about asset factory here.


So, back to topic, with a custom BP class I make sure I load Blueprints I need without hardcoding name of classes into C++ files (hardcoded text and names is a bad practice):

AssetRegistry.Get().GetAssetsByClass
(
	UMyCoreSystemBlueprint::StaticClass()->GetFName() , AssetData, true
);
1 Like

Thank you for the detailed help and also for the second method It is very good.I am trying approach 1 first. I am unable to find this method GetBlueprintFromCDO is it available in UE4 ? I cannot find it : (

That is not an Unreal Engine function either. I have created it somewhere in my libs.
But you don’t need it to make it work, class loading should work without that.

oh ok But I am unable to make it work I must be doing something wrong : ( I have an abstract subsystem class named as UMortarResourceManager and I have blueprint BP_MortarResourceManager. I am trying to load BP_MortarResourceManager so I write this code

TArray<FAssetData>AssetData;

const FAssetRegistryModule& AssetRegistry =
	FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");

AssetRegistry.Get().GetAssetsByClass(TEXT("UMortarResourceManager"), AssetData);

But the blueprint is still not loading


GetAssetsByClass(FName ClassName, TArray& OutAssetData, bool bSearchSubClasses = false);

Add a “true” to the end of function call.
Oh and you probably shouldn’t add any ‘U’, or ‘F’ prefixes either.

still not able to do : ( I am doing this in Begin Play of the main actor.

AssetRegistry.Get().GetAssetsByClass(TEXT("MortarResourceManager"), AssetData,true);

Hmm… I don’t think you should do this stuff mixed with gameplay code.
There could be a step missing somewhere.


Anyway, If nothing of that is working for you, try to have a property somewhere, maybe on a GameInstance:

UPROPERTY(Category="Subsystems", EditAnywhere)
TSubclassOf<UMySubsystem> SystemClass;

Then assign your BP class to that property.
See if that will force your sub class to load by default.

And use that GameInstance as default GameInstance on Project Settings.
When there is a hard reference, it is always loaded:

This is a c++ plugin which is meant to be used with other games so is it feasible to have that in game instance ? : ( as the game would also be having it’s own game instance. Anyways I will debug more as according to you is should work so I must be doing something wrong. I will get back . Thanks for the quick replies : )

Did you actually use the GetAsset() function ?!
You need to call that from the asset data.

This AssetData is 0 size so it is not going in loop at all

I ran this quick test, and the Editor loaded ALL blueprints subclass of UBlueprint::StaticClass():

const FAssetRegistryModule & AssetRegistry =
	FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");

	AssetRegistry.Get().GetAssetsByClass( TEXT("Blueprint") , AssetData, true );

	for (const auto & Data : AssetData)
	{
		LOG::CS_NAME(ESeverity::Warning,  Data.GetAsset()->GetFName()  );
	}


CS: Warning: ActorMacros
CS: Warning: AITesting_MoveGoal
CS: Warning: DefaultBurnInOptions
CS: Warning: ContentBrowserOverview
CS: Warning: FeaturePacks
CS: Warning: ViewportsTutorial
CS: Warning: BlueprintInterfacesEditorOverview
CS: Warning: BlueprintMacroLibrariesEditorOverview
CS: Warning: ClassBlueprintsEditorOverview
CS: Warning: LevelBlueprintEditorOverview
CS: Warning: Tutorial_BP_Class
CS: Warning: Tutorial_BP_Interface
CS: Warning: Tutorial_BP_MacroLib
CS: Warning: … … etc etc loaded all blueprints…

Yes on doing blueprint it works. It also loads resource Manager