[Organizing My Code] Where should Spawn functions be written?

I have a class AMainCharacter inherited from ACharacter. This is part of the constructor:


AMainCharacter::AMainCharacter(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
	static ConstructorHelpers::FObjectFinder<UBlueprint> WeaponBlueprint(TEXT("Blueprint'/Game/FPS/Blueprints/Weapons/BP_Weapon_M4A1.BP_Weapon_M4A1'"));

	if (WeaponBlueprint.Succeeded())
	{
		WeaponSpawn = (UClass*)WeaponBlueprint.Object->GeneratedClass;
	}
}

And this is the BeginPlay() function:


void AMainCharacter::BeginPlay()
{
	Super::BeginPlay();
	
	FActorSpawnParameters SpawnParameters;
	SpawnParameters.Owner = this;

	SpawnParameters.Instigator = Instigator;

	AWeapon* Spawner = GetWorld()->SpawnActor<AWeapon>(WeaponSpawn, SpawnParameters);

	if (Spawner)
	{
		Spawner->AttachRootComponentTo(FirstPersonMesh, "Equip", EAttachLocation::SnapToTarget);
		CurrentWeapon = Spawner;
	}
	
}

This code works fine and as soon as I start the game I get a weapon in my character just like intended. However, since my little game is getting bigger, I want to organize the code. I don’t want to use my character class to spawn weapons around the map. Where should I put my spawn calls?

My first idea was to put them all in GameMode.cpp, but by doing so, how could I access my character Object (not class) from inside GameMode and spawn a weapon in his hands/inventory?

I just can’t find a way to make a pointer to my character object from inside GameMode.

Also, if GameMode.cpp is the wrong way of organizing Spawn functions, could you guys give me some ideias of how to do that?

What I do is put the code in the Pawn/ Character code in a function like SpawnWeapon(WeaponToSpawn, AttachmentSocket). If you are using multiplayer and servers then you’ll need access to remote procedure calls (RPCs) which I’ve found easiest to use the PlayerController for, so it makes sense to keep them all together.

If you want to make them spawn from a pickup or something, then I usually cast the intersecting actor to my pawn class and then call the spawn like:

ACustomPlayerPawn* Player = Cast<ACustomPlayerPawn>( OtherActor) ;
if (Player) { Player->SpawnWeapon(); }

AusPaco thanks for the reply.

But I have another question: is there a way to get the AMainCharacter instance from inside MyGameMode? For example:


AMyGameMode::AMyGameMode(const FObjectInitializer& ObjectInitializer) : Super (ObjectInitializer) 
{
	DefaultPawnClass = AMainCharacter::StaticClass();

        AMainCharacter* characterPtr = GetMainCharacterInstanceAddress(); // I made up this function to give an example of what I want

}

AMyGameMode::BeginPlay()
{
      characterPtr->Destroy();
}


If I could do that, then I could interact with my AMainCharacter instance from inside MyGameMode, which would help in spawning items directly in the character’s inventory.

I’m just not sure I should make this interaction in MyGameMode or in another class.

The standard way to find an actor is to basically go through all actors of a certain class using the actor iterator until you find the one you want:

From the wiki:




void AYourControllerClass::PrintAllStaticMeshActorsLocations()
{
	//EngineUtils.h
	for (TActorIterator<AStaticMeshActor> ActorItr(GetWorld()); ActorItr; ++ActorItr)
	{
		ClientMessage(ActorItr->GetName());
		ClientMessage(ActorItr->GetActorLocation().ToString());
	}
}


Just replace AStaticMeshActor with your custom class.