I can’t figure out how NetworkView.SetScope is supposed to work, can a client set it regarding other clients? Can anyone but the owner set it? Also is it possible to send a NetworkPlayer to a client from the server?
I have this code (not everything, but the relevant parts):
* void SyncPlayerIdentities(){* * for(int i = 0; i < playersIdentity.Length; i++){* _ networkView.RPC(“UpdatePlayerIdentity”, RPCMode.All, playersIdentity*, i); } }*_
* [RPC]* * void UpdatePlayerIdentity(NetworkPlayer player, int i){* * print(“Added player “+i+”, “+player.ipAddress+”:”+player.port);* _ playersIdentity = player; blockedPlayers = false; * }* OnPlayerConnected looks for an open spot in the array to save the player and if it should be blocked or not. SyncPlayerIdentities makes sure that all clients have the same arrays as the server (is only called on the server.) UpdatePlayerIdentity is just the RPC method that updates the arrays to whatever the server wants them to be. Now the problem I have here is that when I try to send the NetworkPlayer to the clients, only an empty NetworkPlayer struct is received in the clients. But it is received with the correct information to the client that is being sent and to the server itself (notice that it is RPCMode.All.) Also, the integer that is being sent with the NetworkPlayer is received just fine. I don’t get it, isn’t NetworkPlayer just a struct with 5 variables? How come they are being received differently by different clients!? Okay, Unity won’t allow NetworkPlayers to be sent regarding other clients to a client, but then how do you use NetworkView.SetScope? I mean, the server shouldn’t be able to set it since it isn’t the owner so I can’t see how this would be done at all._
Yes, it is possible to send a NetworkPlayer between any peers (server-client, client-server, client-client).
Your syncing seems a bit strange. Where do you create your static array and where is it initialized? It looks like you’re searching for the index of the current networkView owner in the array to set the array element? that doesn’t make much sense. That would mean the element is already this user. If that’s the only place where you set the information of the playersIdentity elements, it will never hold any information.
I’ve also used my own “player list”, but i created a dedicated class for each “user”. Well i implemented an authoritative server model, so everything is “owned” by the server
This is a part of my “NetworkUser” class. On each machine there’s an array of those clall instances.
public class NetworkUser
{
public NetworkPlayer netPlayer; // link to Unity's networkconnection for this player
public int netID; // identify the user on the current server [0..Maxplayers-1]
public RegistratedUser regUser; // if user is logged in, this points to a RegistratedUser, otherwise it's null
public ServerUser sUser; // used only by the server
public ENetworkUserState state; // is this playerslot used?
public PlayerObject playerObject; // Player Instance on this machine
public EUserState LastUserState; // UserState from the last Snapshot we are interpolate actually from
// common user infos
public string nickName; // Players Nickname
public int team; // 0=Spectator; 1=Team1/TeamRed; 2=Team2/TeamBlue; ...
public EAnimGroup Class;
public int ping;
// team user infos
private float m_Health = 100.0f;
// [...]
public const int MAX_NETWORK_USERS = 33;
private static NetworkUser[] users = new NetworkUser[MAX_NETWORK_USERS];
public static int PlayerID = -1; // Stores the PlayerIndex of this player (Server==0)
// [...]
}
This was the static information of each player which isn’t updated all the time. The client sends most important data to the server up on connection and the server spreads it to other clients. Basically the array should look identically on each peer. The only exception was the “ServerUser” which holds all relevant data about the player that has no meaning to others. This class also provides properties or function for most attributes which automatically sync the value if needed.
When you don’t want an autoritative setup (which makes some things easier and others more complicated ), you have to define who is managing the player list and who can update this information. When a player connects the server has to assign an identity to this player. In my case the server searches for an empty “slot” and saves the user information together with the NetworkPlayer in this new slot. Now the server sends an RPC to announce the new player by syncing this one slot. It also syncs the whole slot-list on the new player so he get the full list. I used the “state” variable to determine if the slot is in use and in what state the player is, but just from a connection wise point of view. It’s actually a bitflag for various states.
I have to admit that i never used SetScope yet, but the only way it could work is to use it on the owning client. It wouldn’t make much sense if others could set that. I’m not working on a network project at the moment, so i’m a bit rusty with this topic. I always planned to do some test projects on SetScope, but hadn’t the time yet