Spawning BP Class from C++ error : SpawnActor failed because no class was specified

In Project Settings I have set GameMode to → HOMM3GameMode_BP

In this HOMM3GameMode_BP I have set Grid Class to Grid_BP

Then In BeginPlay of HOMM3GameMode I have this spawning code

void AHOMM3GameMode::BeginPlay()
{
	Super::BeginPlay();
	UWorld* MyLevel = GetWorld();

	if (IsValid(MyLevel))
	{
		const FVector Location(0.0f, 0.0f, 0.0f);
		const FRotator Rotation(0.0f, 0.0f, 0.0f);
		FActorSpawnParameters SpawnInfo;
		SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;		
		AActor* Spawned = MyLevel->SpawnActor<AActor>(GridClass, Location, Rotation, SpawnInfo);
		
		Grid = Cast<AGrid>(Spawned);
		
		if (IsValid(Grid))
		{
			UE_LOG(LogTemp, Warning, TEXT("Spawned successfully! New Actor: %s"), *Grid->GetName());
		}
	}
}

What happens is I get → “SpawnActor failed because no class was specified”.
I believe I have made sure that correct GameMode_BP is in Project Settings, and in GameMode I have set correct Class to be spawned.

Hi,

Try changing “GridClass” to “GridClass->GetClass()” in the SpawnActor…

you could add a BeginPlay in your GameMode Blueprint and add a Print Text there to see if that’s being executed.
I would guess that you’re not running the game mode blueprint, but rather running the base.

You could also declare your game mode as abstract, so it can’t be instanced incorrectly.

I will try this. When I tried to use “GridClass->GetClass()” I get crash, it does seem logical that it is running C++ version of GameMode.

Header

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "HOMM3GameMode.generated.h"

/**
 * 
 */
UCLASS()
class YOUR_API AHOMM3GameMode : public AGameModeBase
{
	GENERATED_BODY()
	public:
		UPROPERTY(EditDefaultsOnly,Category="Grid Class")
		TSubclassOf<class AGrid> GridClass;
		virtual void BeginPlay() override;	
};

CPP


#include "HOMM3GameMode.h"
#include "Grid.h"

void AHOMM3GameMode::BeginPlay()
{
	Super::BeginPlay();
	UWorld* MyLevel = GetWorld();

	if (IsValid(MyLevel))
	{
		const FVector Location(0.0f, 0.0f, 0.0f);
		const FRotator Rotation(0.0f, 0.0f, 0.0f);
		FActorSpawnParameters SpawnInfo;
		SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
		if (GridClass != nullptr) {
			AGrid* Spawned = MyLevel->SpawnActor<AGrid>(GridClass, Location, Rotation, SpawnInfo);
			if (Spawned != nullptr)
			{				
				if (GEngine)
					GEngine->AddOnScreenDebugMessage(-1, 5, FColor::Emerald, "Spawned successfully!New Actor :"+ Spawned->GetName());
			}
		}
	}
}

There is no need for casting just spawn directly to AGrid. Also you missed a null check to see if the tsub of grid is set

It might be possible that that’s it, just SpawnActor throwing an error when realizing it’s being asked to spawn an AActor out of an AGrid .

This wont report any logs nor spawn, but I think you are correct with this code, it should work.

I think GridClass is nullptr, and that is because GameMode is “HOMM3GameMode” not “HOMM3GameMode_BP”. BP version has GridClass set, I dont know why it is running the base version of GameMode instead of _BP because I have set it to use _BP in Project Settings.

Also in OutpuLog it reads

LogLoad: Game class is 'HOMM3GameMode'

It should be HOMM3GameMode_BP ?

I also tried to log message in HOMM3GameMode_BP at BeginPlay and this wont log. So I’m pretty sure it’s using C++ version of GameMode, ignoring that I have it set to BluePrint version in ProjectSettings. I dont know how to fix that

FYI My code spawns the agrid actor with no problems reporting it as the bp implementation.

I created new BluePrint from HOMM3GameMode, named it TESTMODEBP and set it in ProjectSettings.
I ran game and still it reads in OutputLog

LogLoad: Game class is 'HOMM3GameMode'

For some reason it seems to be stuck on base Class of my GameMode instead of BP versions

I went to “World Settings” and put GameMode override to my BluePrint versions and after that everything works!
Beats me why it didnt work through ProjectSettings

Perhaps you set the c++ version of your game mode class in your project settings (which has an uninitialized tsubof variable) in place of the bp version where it is set?

I think at some point I mustve accidentally set in the World Settings → Game Mode Override, my C++ GameMode Class. It seems once this was set, it didnt matter what was in Project Settings.
Now I changed World Settings → Game Mode Override to None, and now Project Settings works again. What I choose now as default in Project Settings will be used.

As to when / why I had put the World Settings → Game Mode Override to C++ Class I do not know. Probably at the start of the project I looked at World Settings and maybe there I set it accidenttaly.

But thank you for replies! As a plus you showed me a cleaner version of my spawning code :slight_smile: