Can I spawn blueprints from C++ code?

I have a spawner object, whose job is to regularly spawn fence objects.

Originally, my idea was to have one fence object, whose mesh and material could be assigned at runtime. This approach proved futile, as the fences were always invisible.

I have shifted to an idea where I can use the fence code to create multiple blueprints, each with its own assigned mesh (which accounts for the different possible heights.)

However, I want to know if this is a viable strategy before I roll with it. i.e.

// Called every frame
void AObstacleSpawner::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	switch (state) {
		case SPAWN_PLAY:
			//Get a reference to the game world so we can spawn new objects as needed
			UWorld* World = GetWorld();
			if (World) {
				FActorSpawnParameters SpawnParams;
				SpawnParams.Owner = this;
				SpawnParams.Instigator = GetInstigator();

				//Increment/Decrement timers, spawn objects
				if (SpawnTimer <= 0.0f) {
					//Spawn a new fence obstacle with appropriate height
					AFenceObstacle* NewFence = World->SpawnActor<Fence_BP1>(SpawnParams);	//<--- This is the code I want to validate
					FVector SpawnLocation = FVector(50.0f, 50.0f, 0.0f);	//X = 50 is for debugging purposes only. Y set at 50 is strictly for debug; reset to 0 later.
					NewFence->SetActorLocation(SpawnLocation);
					NewFence->ObstacleSpeed = ObstacleSpeed;

					//DEBUG: Show a prompt indicating that a new fence has been created
					//FVector loc = NewFence->GetActorLocation();
					auto const debug_msg = FString::Printf(TEXT("New fence %i spawned. Height = %i. Spd = %f. X = %f. Y = %f. Z = %f"), FenceIndex, FenceHeight, ObstacleSpeed, SpawnLocation.X, SpawnLocation.Y, SpawnLocation.Z);
					GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, debug_msg);
					//GUBED

					Fences[FenceIndex] = NewFence;
					FenceIndex++;
					if (FenceIndex >= 4) {
						FenceIndex = 0;
					}
					
					SpawnTimer = 5.0f;	//<-- This will be modified later to depend on TimeElapsed
				}
				else {
					SpawnTimer -= DeltaTime;
				}

				int ii;
				FVector CurrentLocation;
				if (TimeToAccel <= 0.0f) {
					ObstacleSpeed += ObstacleAccel;

					//Set the speeds of the fences
					for (ii = 0; ii < 4; ii++) {
						if (Fences[ii] != nullptr) {
							Fences[ii]->ObstacleSpeed = ObstacleSpeed;
							CurrentLocation = Fences[ii]->GetActorLocation();
							if (CurrentLocation.X < -1000.0) {
								Fences[ii]->Destroy();
								Fences[ii] = nullptr;
							}
						}
					}

					TimeToAccel = 5.0f;	//<-- This will be modified later to depend on TimeElapsed
				}
				else {
					TimeToAccel -= DeltaTime;
				}

				TimeElapsed += DeltaTime;
		}
	
	}
}

You could start the fences on scale 0 and as they get closer scale them up.
However to answer the question in the title, you can spawn from blueprints using:

TSubclassOf<AFence> FenceTemplate;
or
TArray<TSubclassOf<AFence>> FenceTemplates;

Then spawn each one.
However you could also consider a struct

FFenceDetail{
  float Height;
TSubclassOf<AFence> FenceTemplate;
}

...
TArray<FFenceDetail> Fences;

Then just lookup the fence with the height you want and spawn it.

GetWorld()->SpawnActor<AFence>(FenceTemplate);

Okay, that’s a good start. Can you help me translate the following line of code to fit that?

//Existing line
AFenceObstacle* NewFence = World->SpawnActor<AFenceObstacle>(SpawnParams);

My first thought, based on what you wrote, is the following:

TSubclassOf<AFenceObstacle> FenceTemplate;
AFenceObstacle* NewFence = World->SpawnActor<AFenceObstacle>(FenceTemplate);

What I’m not sure is how to incorporate the Fence_BP1 blueprint into that code. Please elaborate.

Typically you make the FenceTemplate a UPROPERTY(BlueprintEditable) such that your concrete object has the proper subclass available to instantiate.

You would configure the specific class (for example, your Fence_BP) as the class value for this property on whatever the spawning object is (game mode, controller actor, or whatnot.)

You might also want to use ConstructorHelpers::FClassFinder which lets you find a class by text path (which could be a path to a blueprint class.)

Some more pointers can be found here: TSubclassOf | Unreal Engine Documentation

FenceTemplate can be exposed in your AObstacleSpawner BP so you can set it in the editor.

In code you can then call as you have indicated:

.h

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Whatever") TSubclassOf<class AFenceObstacle> FenceTemplate;

.cpp

if(FenceTemplate){
   AFenceObstacle* NewFence = World->SpawnActor<AFenceObstacle>(FenceTemplate);
}

Okay, so you want me to make my spawner object a blueprint for this?

Right now, the Spawner object is also created at runtime by the player Pawn so that I can sync their states. I’m starting to guess that I should make the spawner object a UPROPERTY of my Pawn class as well, in order to avoid this conflict?

You could yes. Then just drop the Spawner actor in level, on Spawner BeginPlay you can get a reference to your Character and then sync states.