I need help understanding and using RPC!

I am testing this over the network already and not just locally. The issue at hand is that the user who logs in will only receive the “has logged in” message. This also goes for any further chat messages sent.

I have NetworkManager.cs attached to an object of its own. OnConnectedToServer() and OnServerInitialized() runs spawnPlayer():

void spawnPlayer()
{
	player = Network.Instantiate (playerPrefab, new Vector3 ((float)Random.Range (255, 265), (float)251.5, (float)Random.Range (285, 295)), Quaternion.identity, 0) as GameObject;
	player.networkView.RPC("setPlayerName", RPCMode.All, username);
	if(Network.isServer)
		player.GetComponent<Chat>().playerList.Add (player.name);
	else {
		player.networkView.RPC ("addPlayerToList", RPCMode.All, player.name);
	}
}

In here, the player is instantiated and stored as a GameObject. It also calls setPlayerName which simply sets their name to Player_USERNAMEHERE and also updates the Text Mesh above their head for all other players to see. This, surprisingly enough, works. All other players can see the names properly.

setPlayerName is in the Player.cs script. This script is attached to the playerPrefab that is in NetworkManager.cs:

[RPC] void setPlayerName(string username) {
	name = "Player_" + username;
	savedUsername = name.Substring (7);
	TextMesh playerName = GetComponent<TextMesh>();
	playerName.text = savedUsername;
	if(networkView.isMine) {
		networkView.RPC("setPlayerName", RPCMode.OthersBuffered, savedUsername);
		networkView.RPC ("print", RPCMode.AllBuffered, "" + savedUsername + " has logged on.");
	}
}

It calls print as well so it will display “Player has logged in.” This is where I have been having trouble.

print() is in Chat.cs which is also attached to the playerPrefab:

[RPC] void print(string string_)
{
	log.Add (string_);
	if(log.Count >  maxLogMessages) {
		log.RemoveAt(0);
	}
}

It will add it to the list, log, and OnGUI() will print it out to the label which creates the chat box. It will display it on the user’s screen but not other user’s screens. Pretty much as if it was never sent.

Pertaining the issue where no players can converse with each other, here is how I use RPC to also use print() While I don’t think It’s important to be read, it’s there if it may help to solve my issue:

						List<string> charList = new List<string>();
						foreach(char c in stringToEdit) {
							charList.Add (c.ToString());
						}
						
						int limit = 1;
						string brokenString = "";
						bool brokenStringLooped = false;
						foreach(string s in charList) {
							if(!brokenStringLooped && limit == (25 - (GetComponent<TextMesh>().text + ": ").Length)){
								brokenString = brokenString + s;
								networkView.RPC ("print", RPCMode.AllBuffered, GetComponent<TextMesh>().text + ": " + brokenString);
								brokenStringLooped = true;
								brokenString = "";
								limit = 1;
							}
							else{
								if(limit == 25){
									brokenString = brokenString + s;
									networkView.RPC ("print", RPCMode.AllBuffered, brokenString);
									brokenString = "";
									limit = 1;
								}
								else{
									brokenString = brokenString + s;
									limit++;
								}
							}
						}
						if(brokenString!=""){
							if(!brokenStringLooped)
								networkView.RPC ("print", RPCMode.AllBuffered, GetComponent<TextMesh>().text + ": " + brokenString);
							else
								networkView.RPC ("print", RPCMode.AllBuffered, brokenString);
							brokenString = "";

The majority of what is written there is simply what I wrote to break the string in chunks so it fits the label and the ScrollView.

Going back to spawnPlayer(), addToPlayerList() does not add the player’s name to the list at all. This is also an issue. addToPlayerList() is also in Chat.cs which is attached to the playerPrefab:

[RPC] void addPlayerToList(string playerName)
{
	if(Network.isServer) {
		playerList.Add(playerName);
	}
}

Successes:
-Users can see each other move
-Users control their own characters
-Each player’s overhead name (Text Mesh) is their own username.

Issues:
-print() does not send text over the network. It only displays on the senders screen.
-playerList is not being updated.

Questions about RPC:
-What is the difference between buffered and the rest of the RPCModes? I’ve been alternating between them to get a clear understanding. I’ve done this about 10 times and still can’t see what’s the difference.
-When should RPC be used?

Buffered RPCs are for connected players on the future. When a new player connect, will not receive the RPC if has been sent without buffered option. For example having a scene with dead body where die action has been sent by not buffered RPC, already players on scene are sawing the body but a new connected player will not see the body. Be careful when use buffered option, it’s not for all the things like players movements, it’s important the buffered RPC collection to be small in size.

I am not sure (I didn’t read all the code) but I think playerList not updated due addPlayerToList() is executed only on server side by if(Network.isServer) condition.
I think there have to be something like: a client use RPC.Server (add me), then the server use RPC.AllBuffered (push me to list).

I finally solved this issue after realizing how RPC works. I rewrote all my scripts from scratch and began adding some of my old scripts. Eventually, I saw that RPC basically sends the information to its (Clone) on the other side.

RPCMode.All, sends it to all .exe Applications that has itself cloned on there.
RPCMode.Others, sends it to all .exe Applications that has itself cloned on there other than itself.
RPCMode.Server, sends it to only the server’s copy of itself.

So, I simply made it so the chat system, and everything else that had to do with globally applying things, that it was created beforehand in something that would manage the network itself. Anything to be applied to individual characters, such as overhead names and colors, was done on that individual character itself and RPC was passed through RPCMode.Others so that it would be applied to any other clones on the network that had been instantiated.

I feel like I pretty much understand how RPC works now. I hope that what I wrote helps others understand it if they so happen to cross by this post.