Hi,
recently i have been trying to setup a server to which i want to connect with several clients (just a basic multiplayer game). I have a little experience with doing peer to peer multiplayer via steam, with a collectible card game i programmed.
Now i want to take things a step further by running a turnbased game on a dedicated server. On short term i just want to host a server locally an playtest with my fellow devs by using hamachi. Later on when testing with players becoms important i want to switch the server to aws.
So far i have been able to host a server locally and on aws and i was able to connect several clients to this server. I have used the third person template and the movement of the clients was replicated.
But for my turnbased game i want to send objects to the server or to my clients. So far with my game on steam i have been using the UFUNCTION(Client) / UFUNCTION(Server) flags.
So for testing purposes i wanted to host a server, connect with several clients to it and have the clients print screenmessages, to test if it works. Unfortunatly it didn’t.
My code so far:
In my gamemode i stored the connected playercontrollers to my networkmanager and ran the TestFunction().
void AGameModeIngame::PostLogin(APlayerController* NewPlayer) {
Super::PostLogin(NewPlayer);
ConnectedPlayers++;
if (ConnectedPlayers == 1) {
UNetworkManager::GetNetworkManager()->World = GetWorld();
if (UKismetSystemLibrary::IsServer(NewPlayer)) {
UNetworkManager::GetNetworkManager()->AddHostController(NewPlayer);
}
else {
UNetworkManager::GetNetworkManager()->AddClientController(NewPlayer);
}
UNetworkManager::GetNetworkManager()->TestFunction();
}
else if (ConnectedPlayers == 2) {
UNetworkManager::GetNetworkManager()->AddClientController(NewPlayer);
}
else {
Logout(NewPlayer);
}
}
My networkmanager is a singleton which stores the connected playercontrollers and calls the functions to test the replication.
UNetworkManager* UNetworkManager::Instance;
UNetworkManager::UNetworkManager() {}
UNetworkManager* UNetworkManager::GetNetworkManager()
{
if (!Instance) {
Instance = NewObject<UNetworkManager>();
//this statement ensures that the Class is never garbage collected away.
//another option would be to declare instance as an UProperty, which is impossible for static variables,
//or to permanently store a pointer to it in Gamestate or a similar class.
Instance->AddToRoot();
}
return Instance;
}
void UNetworkManager::AddClientController(APlayerController* _client)
{
Clients.Push(_client);
}
void UNetworkManager::AddHostController(APlayerController* _client)
{
Host = _client;
}
void UNetworkManager::TestFunction()
{
World->GetGameState()->GetWorldTimerManager().SetTimer(FTestHandle, this, &UNetworkManager::TestFunction, 2.0f, true, 2.0f);
for (APlayerController* Client : Clients) {
Cast<APlayerControllerTest>(Client)->Client_TestNetworkz_Implementation();
}
if (Host) {
Cast<APlayerControllerTest>(Host)->Server_TestNetworkz_Implementation();
}
}
Finally on my playercontrollers i just run the functions to print to screen.
void APlayerControllerTest::Server_TestNetworkz_Implementation()
{
GEngine->AddOnScreenDebugMessage(-1, 10, FColor::Red, FString(“Testing the Server to Check if it Works”));
}
void APlayerControllerTest::Client_TestNetworkz_Implementation()
{
GEngine->AddOnScreenDebugMessage(-1, 10, FColor::Red, FString("Testing the Server to Check if it Works"));
}
bool APlayerControllerTest::Client_TestNetworkz_Validate()
{
return true;
}
bool APlayerControllerTest::Server_TestNetworkz_Validate()
{
return true;
}
My playercontroller.h :
UFUNCTION(Client, reliable, withvalidation)
void Client_TestNetworkz();
bool Client_TestNetworkz_Validate();
UFUNCTION(Server, reliable)
void Server_TestNetworkz();
bool Server_TestNetworkz_Validate();
I hope you guys can tell me what i am doing wrong or if i have the wrong angle to what i want to do.
Cheers,
Marogaz