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.