Spawning players at player start

So i am new to Unreal and c++ (came from unity and C#) but i decided to try and learn multiplayer functionality a bit and figure out from there.

The issue i am facing right now is that in my game mode script, I am attempting to spawn in a player at each player start (following this: - YouTube and attempting to convert the blueprints to c++ to help me learn) but I am having some issues.

Currently I am having 5 players spawn, but only one is rendered correctly, and the rest are there and have collision, but seem busted and no visuals are there (I am using the fps template but i added a sphere to the playercontroller class so that I could see if they where spawned)

Here is my code:
Header .h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "GameFramework/PlayerStart.h"

#include "CodeName_FPSGameGameMode.generated.h"

UCLASS(minimalapi)
class ACodeName_FPSGameGameMode : public AGameModeBase
{
	GENERATED_BODY()

public:
	ACodeName_FPSGameGameMode();

	UPROPERTY(EditAnywhere)
	int Max_Players;

	int index;
	TArray<AActor*> currPlayers;

	//int spawnLoc[] = {1, 0, 0, 0, 0};

	//Finds the playerstart and assigns them to an array
	void GetPlayerStartPoints();

	void SpawnPlayers(TArray<APlayerStart*> arrayToPrint);

protected:
	virtual void BeginPlay() override;
};

Main Code .c

#include "CodeName_FPSGameGameMode.h"
#include "CodeName_FPSGameHUD.h"
#include "CodeName_FPSGameCharacter.h"
#include "GameFramework/Actor.h"
#include "Engine/Engine.h"
#include "GameFramework/PlayerStart.h"
#include "Kismet/GameplayStatics.h"
#include "UObject/ConstructorHelpers.h"
#include "EngineUtils.h"

ACodeName_FPSGameGameMode::ACodeName_FPSGameGameMode()
	: Super()
{
	// set default pawn class to our Blueprinted character
	static ConstructorHelpers::FClassFinder<APawn>
	PlayerPawnClassFinder(TEXT("/Game/FirstPersonCPP/Blueprints/FirstPersonCharacter"));
	DefaultPawnClass = PlayerPawnClassFinder.Class;

	// use our custom HUD class
	HUDClass = ACodeName_FPSGameHUD::StaticClass();
}

//Gets all the actors for me of my choosing and puts them into an array
template<typename T>
void FindAllActors(UWorld* World, TArray<T*>& Out)
{
	for(TActorIterator<T> It(World); It; ++It)
	{
		Out.Add(*It);
	}
}
/* Spawns given class and returns class T pointer, forcibly sets world position. 
template< class T >
T* SpawnActor
(
    UClass* Class,
    FVector const& Location,
    FRotator const& Rotation,
    AActor* Owner=NULL,
    APawn* Instigator=NULL,
    bool bNoCollisionFail=false
)
{
	return (Class != NULL) ? Cast<T>(()->SpawnActor(Class, NAME_None, &Location, &Rotation, NULL, bNoCollisionFail, false, Owner, Instigator)) : NULL;
}*/

void ACodeName_FPSGameGameMode::BeginPlay()
{
	Super::BeginPlay();

	GetPlayerStartPoints();
}

void ACodeName_FPSGameGameMode::GetPlayerStartPoints()
{
	TArray<APlayerStart*> playerStart;
	FindAllActors((), playerStart);

	Max_Players = 5;

	for(int i = 0; i < Max_Players; i++)
	{
		for(auto obj: playerStart)
		{
			//UnCaching anything currently possed in the world
			APlayerController* controller = UGameplayStatics::GetPlayerController((), index);
			//controller->UnPossess();

			//converting the tags to a name
			FName psTag = obj->PlayerStartTag;
			FString indexToString = FString::FromInt(index);
			FName indexStringToName = FName(*indexToString);

			//location to spawn the actor
			FVector loc = obj->GetActorLocation();
			FRotator rot = obj->GetActorRotation();
			FActorSpawnParameters SpawnInfo;

			//assigning and spawning
			if(psTag == indexStringToName)
			{
				UGameplayStatics::CreatePlayer((), index, true);

				APawn* characterNew = ()->SpawnActor<ACodeName_FPSGameCharacter>(loc, rot, SpawnInfo);

				controller->Possess(characterNew);
				
				currPlayers.AddUnique(obj);
			}
			else
			{
				UGameplayStatics::CreatePlayer((), index, true);

				APawn* characterNew = ()->SpawnActor<ACodeName_FPSGameCharacter>(loc, rot, SpawnInfo);

				controller->Possess(characterNew);
				
				currPlayers.AddUnique(obj);
			}
		}
	}
}

Thank you in advance! I realize you may need some additional info so just let me know, again im just learning still so I dont know what else to include.

Each player have a own player controller when you call CreatePlayer the new PlayerController is created and returned by the function, your code gets single created at beginning spawns actor create player and uses that player 1 controller gets at beginning to posses all spawned pawns which also cause immediate unpossesion (which may freak out pawn actor code) except the last one

So get Player controller of creating with the player and posses pawn with that.

            APlayerController* NewPC = UGameplayStatics::CreatePlayer((), index, true);

             APawn* characterNew = ()->SpawnActor<ACodeName_FPSGameCharacter>(loc, rot, SpawnInfo);

             NewPC->Possess(characterNew);
             
             currPlayers.AddUnique(obj);

Note that your code will only work with local multiplayer, in networked multiplayer PlayerController is created automatically when new player joins, you can catch that on PostLogin event

Also note that UE4 got build in spawn system, when you set default pawn in project settings it is activated, and everything is delt by GameMode code, there events and functions to track what it doing and alter it behavior. Normally you use that or else you make some out of ordenery gameplay

Read about UE4 Game framework:

Remember that Unity is more bare bone engine while UE4 already comes with lot of things and out of the box and work by default and usually don’t require much of a code to make things run. Spawn system is one of them.

Thank you!! This helps a lot!!!