Best Way To Spawn a New Pawn with Specific Controller in C++?

What is the best way to spawn a new pawn with a specific controller in C++?

Here’s what I’m doing:

APawn* NewPawn = ()->SpawnActor<APawn>();
NewPawn->AIControllerClass = AIsisAIControllerRandom::StaticClass();
NewPawn->SpawnDefaultController();

This seems awkward for a couple of reasons. First, I’m modifying a variable (AIControllerClass) directly, which is not good practice. It also seems “incorrect” to use SpawnDefaultController - I feel I should be able to attach a controller directly that I spawn. I checked the docs for Pawn & AIController and didn’t see anything obviously better.

Is there something I’m missing?

Thanks for your time.

Settings varable directly is ok if there is no function for it, which AIControllerClass don’t have because it meant to be used in defaults, usally variables that ment to be used with only function are protected and you can’t access them directly outside of the related class. Calling SpawnDefaultController() is also fine… just look on the it’s code:

void APawn::SpawnDefaultController()
{
	if ( Controller != NULL || GetNetMode() == NM_Client)
	{
		return;
	}
	if ( AIControllerClass != NULL )
	{
		FActorSpawnParameters SpawnInfo;
		SpawnInfo.Instigator = Instigator;
		SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
		SpawnInfo.OverrideLevel = GetLevel();
		SpawnInfo.ObjectFlags |= RF_Transient;	// We never want to save AI controllers into a map
		AController* NewController = ()->SpawnActor<AController>(AIControllerClass, GetActorLocation(), GetActorRotation(), SpawnInfo);
		if (NewController != NULL)
		{
			// if successful will result in setting this->Controller 
			// as part of possession mechanics
			NewController->Possess(this);
		}
	}
}

Alternatively you can simply spawn you AIController and make it posses the pawn with Possess function… which above function do anyway. Only issue with above function i can see is fact that if you set default AI controller and it will spawn normally then it wont be destroyed and may stay with the world until world gets destroyed, but if AIControllerClass is null by default then it should be ok to use this function.

I tell that assuming that you are aware that you can set defaults in constructor, because in normal use case you should set AIControllerClass in pawn constructor and also set AutoPossessAI in it. What you trying to do is good only if you plan to setup AIController mid way of pawn life cycle or you want to spawn pawn with different AIController on each spawn.

“I tell that assuming that you are aware that you can set defaults in constructor, because in normal use case you should set AIControllerClass in pawn constructor and also set AutoPossessAI in it.”

I was not aware of this, thank you! I kept looking for a method in Pawn to set the controller, instead of checking the constructor. I do not have the specific use case you mentioned “setup AIController mid way of pawn life cycle…” so setting the Controller in the constructor is the right choice.

Thanks!