Using RPC call to send the list of players works fine, but when I do it the same way with the selected characters name, it will not work.
The selected character will be the local selected character name on both players slots in the multiplayer room. This image can explain it: Dropbox - Error - Simplify your life
on the server the character is named server and is of type archer while on the client its named client and is of type mage.
Row 93 sets the value on the GUI while row 45-86 are the RPC calls.
It should say like this on both clients:
Player: server: Archer
Player: client: Mage
public class MultiplayerRoom : MonoBehaviour
{
// character lists
private string[] fileList; // list of files in character folder
private int selectedItemIndex; // index of selected item in dropdown list
private Character currentCharacter; // selected character
// serialization
private Serializer serializer = new Serializer(); // serializer
// ComboBox
private string[] itemList; // list of items
private Rect comboBox; // box positioning
private string selectedItem = ""; // current selected item, empty as a default value if no items exists
private bool editing = false; // keep the list open or not (start as closed)
// level list toggeling
private int selectedLevelIndex = -1; // level selected at character selection screen
// level data
private LevelData levelData = new LevelData(); // object containing level data
private List<Level> levelList; // list of levels
// networking
private List<NetworkPlayer> listOfPlayers = new List<NetworkPlayer>(); // list of connected players
private List<String> selectedCharacters = new List<String>(); // list of connected players chosen characters
void Start()
{
// get level data
levelList = levelData.GetList();
selectedLevelIndex = 0;
selectedItemIndex = 0;
}
void OnGUI()
{
if(Network.peerType == NetworkPeerType.Disconnected)
{
// TODO: add room loading GUI with cancel button and a timer
Debug.Log("Disconnected");
}
else
{
// set style of boxes
GUI.skin = gameObject.GetComponent<GUIStyler>().mainMenuSkin;
// Make a background box
GUI.Box(new Rect((Screen.width / 2) - 150, (Screen.height / 2) - 300, 300, 400), "Multiplayer Game");
// character ComboBox
comboBox = new Rect((Screen.width / 2) - 80, (Screen.height / 2) - 255, 165, 25);
if (GUI.Button(comboBox, selectedItem))
{
editing = true;
}
Event e = Event.current;
if (editing)
{
for (int i = 0; i < itemList.Length; i++)
{
if (GUI.Button(new Rect(comboBox.x, (comboBox.height * i) + comboBox.y + comboBox.height, comboBox.width, comboBox.height), itemList*))*
-
{*
_ selectedItem = itemList*;_
_ selectedItemIndex = i;*_
* currentCharacter = serializer.Deserialize(fileList[selectedItemIndex]);*
* editing = false;*
* }*
* }*
* if (e.type == EventType.MouseDown)*
* {*
* editing = false;*
* }*
* }*
* else*
* {*
* // change character and push the data over the network only if it has changed*
* if( selectedItem != selectedCharacters[PlayerIndexToInt(Network.player)] )*
* {*
* networkView.RPC(“SetSelectedCharacter”, RPCMode.AllBuffered, PlayerIndexToInt(Network.player));*
* }*
* }*
// list of connected players
foreach (NetworkPlayer player in listOfPlayers)
{
_ GUI.Label(new Rect((Screen.width / 2) - 130, (Screen.height / 2) - 225 + (int.Parse(player.ToString()) * 30), 200, 50), "Player: " + selectedCharacters[PlayerIndexToInt(player)]);_
}
// level list
GUILayout.BeginArea(new Rect(Screen.width / 2 - 130, (Screen.height / 2) - 150, 250, 200));
if (fileList.Length > 0 && currentCharacter != null)
{
for (int i = 0; i < currentCharacter.characterLevel; i++)
{
if (GUILayout.Toggle(selectedLevelIndex == i, levelList_.Number + ": " + levelList*.Name, “toggle”))
{
selectedLevelIndex = i;
}
}
}*_
GUILayout.EndArea();
// buttons
if (GUI.Button(new Rect((Screen.width / 2) - 130, (Screen.height / 2) + 50, 80, 20), “Back”))
{
Network.Disconnect();
gameObject.GetComponent().SetGUI(false, false, false, false, false, false, false, false, true, false, false);
}
}
}
void Update()
{
fileList = serializer.ListFiles(); // create list of files
itemList = new string[fileList.Length];
// get character list
for (int i = 0; i < fileList.Length; i++)
{
Character aCharacter = serializer.Deserialize(fileList*);*
itemList = aCharacter.characterName + ": " + aCharacter.characterClass;
}
// select first option by default if any exists
if (itemList != null && itemList.Length > 0 && selectedItem.Equals(“”))
{
selectedItem = itemList[0];
currentCharacter = serializer.Deserialize(fileList[0]);
}
}
///
/// Create a list of connecting players
///
/// connecting player
void OnPlayerConnected(NetworkPlayer player)
{
networkView.RPC(“PushListOfPlayers”, RPCMode.AllBuffered, player);
* networkView.RPC(“AppendNewCharacter”, RPCMode.AllBuffered);*
}
///
/// Add the server creator to the list of players
///
void OnServerInitialized()
{
* networkView.RPC(“PushListOfPlayers”, RPCMode.AllBuffered, Network.player);*
* networkView.RPC(“AppendNewCharacter”, RPCMode.AllBuffered);*
}
* ///
* /// Pushs the list of players.*
* ///
* /// Player to add to the list*
* [RPC]*
* void PushListOfPlayers(NetworkPlayer player)*
* {*
* listOfPlayers.Add(player);*
* }*
* ///
* /// Appends a new character to be used in the player list.*
* ///
* [RPC]*
* void AppendNewCharacter()*
* {*
* selectedCharacters.Add(selectedItem);*
* }*
* ///
* /// Sets the selected character to be displayed in the player list.*
* ///
* /// index in selected characters list*
* [RPC]*
* void SetSelectedCharacter(int index)*
* {*
* selectedCharacters[index] = selectedItem;*
* }*
* ///
* /// Converts players index to int.*
* ///
* /// The index as an int*
* /// Player.*
* private int PlayerIndexToInt(NetworkPlayer player)*
* {*
* String thisPlayer = player.ToString(); // get id of player*
* int thisPlayerInt = int.Parse(thisPlayer); // convert id to int*
* return thisPlayerInt;*
* }*
}
thank you, but how am I supposed to sync a list if not in the RPC method?
– GatsuaWell, you have to use RPCs to sync your data, but make sure the data is consistant and reliable which your "PlayerIndexToInt" isn't. Also, like i said using dynamic structures will just create more problems. What if a player leaves mid-game? Do you remove it from your player list? That means all indices would change.
– Bunny83Thank you, very informative!
– Gatsua