How to load a blueprint class and spawn it in C++?

I have an actor class named AStatucActor in C++ and a blueprint class named BP_StatueActor derived from the actor. I saved the blueprint as shown below.

statue

I want to spawn the blueprint from within a level script as follows:

UCLASS()
class JAN05_API AMyLevelScriptActor : public ALevelScriptActor
{
	GENERATED_BODY()
		AMyLevelScriptActor();
	void BeginPlay() override;
	TSubclassOf<AActor> ActorToSpawn;
};

AMyLevelScriptActor::AMyLevelScriptActor()
{
	static ConstructorHelpers::FClassFinder<AActor> AssetFile(TEXT("/Game/BP_StatueActor.BP_StatueActor"));
	if (AssetFile.Class != nullptr)
		ActorToSpawn = AssetFile.Class;
}

void AMyLevelScriptActor::BeginPlay()
{
	Super::BeginPlay();
	if (ActorToSpawn)
		GetWorld()->SpawnActor<AActor>(ActorToSpawn, FTransform());
}

Unfortunately, the AssetFile.Class is always nullptr.

The error I found in Output Log:

Error: CDO Constructor (MyLevelScriptActor): Failed to find /Game/BP_StatueActor.BP_StatueActor

Question: How to load a blueprint class and spawn it in C++?

I got the solution. The correct path must be ended with _C. So I have to change the path as follows:

"/Game/BP_StatueActor.BP_StatueActor_C"

Note: there is a postfix _C at the end.

Another solution (by Daniel Marshall): Just take the characters before the dot as the path:

"/Game/BP_StatueActor"

3 Likes

From what I understand, gaining direct access to a BP from C++ is not very easy or practical. I’m still relatively new to using C++ but here is what I’ve done thus far to help me, so maybe the logic can be applied to your needs or get your wheels spinning anyway.

I’ve needed to gain access to Widget BP and Component BP’s from my C++ classes. So what I did for example, with my Widget was I create a C++ child class of a UserWidget called PrimaryWidget and on my Player Character, I have the following

PlayerCharacter.h

// Property that assigns the BP object
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
TSubclassOf<UUserWidget> HUD;

// Holds the reference to our Inventory Widget Screen that we use to reference the BP
// UPrimaryWidget is the name of my base widget class where HUD widget is derived from
UPROPERTY(VisibleInstanceOnly)
class UPrimaryWidget* HUDWidgetReference;

PlayerCharacter.cpp

void APlayerCharacter::BeginPlay()
{
check(HUD)

HUDWidgetReference = Cast<UPrimaryWidget>(CreateWidget(PlayerControllerRef, HUD));

Just make sure to then go into the player character assign the BP to the HUD property inside of blueprints, without it the check(HUD) will throw an exception. I then have access to the blueprint from my Player Character. This isn’t an exact fix, you still can’t access properties and methods you create inside the blueprint. In this case, it is best to have a C++ parent class that has the default properties and methods assigned to it, then the methods and properties implemented inside the blueprint. This will allow you access to those properties and methods then.

I’m sure this exact example won’t help you in your exact situation but perhaps it can get your gears grinding to find the right example for you. You want to try and eliminate as many hard reference calls to files (AssetFile(TEXT("/Game/BP_StatueActor.BP_StatueActor"))) as much as possible. Move a file and the game crashes.

Good luck, hope I was even slightly helpful!

1 Like

Thank you. I already found the culprit. _C is mandatory for the path to the blueprint class. It is a convention made by UE. :slight_smile:

Thanks, I’m just sitting here thinking about my project moving forward and realizing that when it comes time to spawn blueprint actors from C++ that I may have a difficult time using the method I mentioned. Thanks for finding this solution, I’m sure I’ll be using it!

I just got another solution: You just need to take the characters before the dot as the path. See my edited answer. It might be useful for your. :slight_smile:

What you should do is add a TSubclassOf to your code, make a Blueprint of the Thing that Spawns the Thing, and specify the blueprint in there.

ie, class A spawns a BP Z …

make a Blueprint B that is of class A, and inside it specify BP Z to spawn.

1 Like

I know your approach before asking this question. Thank you.

This should really be the solution for this post.

1 Like