- Home /
The question is answered, right answer was accepted
Rpc logic with bools, using tutorial scripts, can't find the flaw
I've got 2 scripts - PlayerDeath and MatchManager. MatchManager has a static List players and 3 static methods - AddPlayer, RemovePlayerAndCheckWinner and GetWinner. PlayerDeath script on the other hand has some RPCs in it, most notably when the player finishes or loses the level. There are 2 players, when one of them wins, the other one loses. Worked out well for me till now - I am trying to assign a bool that each player has finished the game, and after 2 bools are true, I can move on with other stuff. Thing is, with my current script I can't seem to achieve what I want.
When the hosting player finishes the game, and client tries to, he can't. The bool simply doesn't record. But when the client finishes the game first, the host's bool records and it is all good. Logic somewhere is flawed, but I can't pinpoint the problem, and I've been tinkering with it for quite some time. I know they look really simple, but I was working off of a tutorial and probably didn't comprehend these scripts' logic fully. Maybe someone here could point me in the right direction. Thank you.
Here is the code - Relevant PlayerDeath methods and RPCs. This first method SetFinishBools is called, when a player collides with the Finish line.
public void SetFinishBools() //Called when player collides with Finish line
{
if (!isServer)
return;
RpcSetHostBool();
if (MatchManager.RemovePlayerAndCheckWinner(this))
{
PlayerDeath player = MatchManager.GetWinner();
player.RpcSetOpponentBool();
}
return;
}
[ClientRpc]
void RpcSetHostBool()
{
if (isLocalPlayer)
netManager.hostFinishedLevel = true; //A Syncvar bool from another script
}
[ClientRpc]
void RpcSetOpponentBool()
{
if (isLocalPlayer)
netManager.opponentFinishedLevel = true; //A Syncvar bool from another script
}
And the MatchManager:
public static List<PlayerDeath> players = new List<PlayerDeath>();
public static void AddPlayer(PlayerDeath player)
{
players.Add(player);
}
public static bool RemovePlayerAndCheckWinner(PlayerDeath player)
{
players.Remove(player);
if (players.Count == 1)
return true;
return false;
}
public static PlayerDeath GetWinner()
{
if (players.Count != 1)
return null;
return players[0];
}
Answer by Akusan · Sep 07, 2017 at 02:27 PM
Add a script for host migration so that when server or host is disconnected then the a client automatically becomes the host
So, something like this?: https://docs.unity3d.com/$$anonymous$$anual/UNetHost$$anonymous$$igration.html
Try it and see if it works. $$anonymous$$aybe ins$$anonymous$$d of adding or removing player, just move them ins$$anonymous$$d by disabling their control, changing their transform position, re-enabling control. That way you don't mess up the onstart initializations
I looked through Google and someone said that it can be easily distinguished between a server and a client with an if (isServer) and if (!isServer), but when I looked up Network Information in Inspector both players in my lobbyPanel and in game (host and client) are marked as server. How is that possible :/
Follow this Question
Related Questions
Can I run unity with this system? 3 Answers
Is unity uses rendering from the cpu or gpu ? 2 Answers
How to make sure than one script affect the player of the specific client, and not the other 2 Answers
How do I use UNetWeaver.dll during runtime? 0 Answers
Getting a mix of warnings in multiplayer 0 Answers