- Home /
Sending RPC to add playerName
I'm trying to make it so, whenever a Player Connects to the server, it transfer it's selected name, over to the RPC, which then will update the Player Game Object for everyone. But this seems to give following error:
Sending RPC failed because 'setPlayerName' parameter 0 (UnityEngine.GameObject) is not supported.
This is my code:
void OnConnectedToServer() {
GameObject newPlayer = (GameObject)Network.Instantiate(newPlayerPrefab, new Vector3(0,0,0), Quaternion.identity, 0);
networkView.RPC("setPlayerName", RPCMode.AllBuffered, newPlayer);
}
[RPC]
void setPlayerName(GameObject newPlayer) {
newPlayer.name = "Player_" + playerName;
}
If this isn't the correct way to change the new spawned player's gameObject
name, then please help me with a way, that actually is the correct way.
it's possible the notes on this Q could be relevant to what you are doing...
http://answers.unity3d.com/questions/326626/games-with-multiple-maps.html
Answer by whydoidoit · Mar 20, 2013 at 10:47 AM
Yes you can't send a GameObject to the over RPC - it looks like you should be sending a string though - with the name...
That is not an option. Since you can see, I need the newly instansiated gameObject, to have it's name changed, and for that to correctly work, so it shows the same name for everyone, it has to be in RPC.
Answer by hrlarsen · Mar 20, 2013 at 11:49 AM
would it work if you do like this (as whydoidoit also tried to explain)
void OnConnectedToServer() {
GameObject newPlayer = (GameObject)Network.Instantiate(newPlayerPrefab, new
string playerName = newPlayer.name;
Vector3(0,0,0), Quaternion.identity, 0);
networkView.RPC("setPlayerName", RPCMode.AllBuffered, playerName);
}
[RPC]
void setPlayerName(string playerName) {
newPlayer.name = "Player_" + playerName;
}
Not really. You use the newPlayer variable in your RPC function but it is declared inside OnConnectedToServer. Even when it's declared outside, it won't be set on other clients.
Answer by Bunny83 · Mar 20, 2013 at 12:01 PM
You missed one of the main concepts of NetworkViews. A NetworkView is the only link between a GameObject on different peers. Your playerprefab should have a NetworkView attached. You should send the RPC over this NetworkView. Of course your setPlayerName function need to be in a script attached to the player itself.
void OnConnectedToServer()
{
GameObject newPlayer = (GameObject)Network.Instantiate(newPlayerPrefab, new Vector3(0,0,0), Quaternion.identity, 0);
newPlayer.networkView.RPC("setPlayerName", RPCMode.AllBuffered, "PlayerNameHere");
}
// In a script on your player prefab:
[RPC]
void setPlayerName(string playerName)
{
name = "Player_" + playerName;
}
Answer by jaxx0rr · Jun 03, 2014 at 08:02 AM
I searched alot for this and did not find anything usable.. so I wrote this (javascript):
#pragma strict
var ServerIP:String = "192.168.1.2";
var ServerPort:String = "30000";
var screen: String;
var PlayerName: String = "";
var displayError: String;
var selfDC: boolean;
function Start () {
Application.runInBackground = true;
Screen.fullScreen = true;
//origTex = GUI.skin.textField.normal.background;
init();
}
function init(){
screen = "main";
displayError = "";
selfDC = false;
}
function OnGUI () {
var w: int = 300;
var h: int = 50;
var x: int = Screen.width/2-w;
var y: int = Screen.height/2-200;
if (Network.peerType == NetworkPeerType.Disconnected){
screen = "main";
} else {
screen = "character";
}
GUI.skin.button.fontSize = 16;
GUI.skin.label.fontSize = 16;
GUI.skin.textField.fontSize = 16;
GUI.skin.textField.alignment = TextAnchor.MiddleCenter;
if (screen=="main") {
GUI.Label (Rect (10, 10, w, h), "IP:"+Network.player.ipAddress);
GUI.Label (Rect (x+160, y-(h+10), w, h), "Name:");
PlayerName = GUI.TextField (Rect (x+w-90, y-h-10, w, h), PlayerName, 25);
if (GUI.Button(Rect(x,y,w*2+10,h), "Host")){
startServer();
}
ServerIP = GUI.TextField (Rect (x, y+h+10, w, h), ServerIP, 25);
if (GUI.Button(Rect(x+w+10,y+h+10,w,h), "Join")){
selfDC = false;
shared_playerList = new Array();
var result = Network.Connect(ServerIP,parseInt(ServerPort));
Debug.Log(result.ToString());
}
}
if (screen=="character") {
if (GUI.Button(Rect(Screen.width-(w+10),10,w,h), "Back")){
selfDC = true;
resetPlayerInfo();
Network.Disconnect();
}
}
if (displayError != "") {
GUI.Box(Rect(Screen.width/2-200,Screen.height/2-40,400,220), "\n"+displayError);
if (GUI.Button(Rect(Screen.width/2-50,Screen.height/2+120,100,40),"OK")){
displayError = "";
}
}
var pl = "SHARED PLAYER LIST:";
for(var i:int=0;i<shared_playerList.length;i++) {
if (i>0) pl += " ";
pl += shared_playerList[i];
}
GUI.Label (Rect (300, 10, 600, 200), pl);
}
function ErrDialog(txt:String){
displayError = txt;
}
//since associative arrays arent really unitys strong point we have to make 2 string arrays
var server_playerList : Array; // this holds the list of player names on server only (for processing)
var server_guidList : Array; // this holds the list of unique network ids
var totalPlayers : int; //this will keep the total number of players
resetPlayerInfo();
var shared_playerList : Array; // this holds the player list on server + clients for display
/////////////////////////////////////////////////////////////////////////////
// SERVER SIDE FUNCTIONS
/////////////////////////////////////////////////////////////////////////////
function startServer(){
resetPlayerInfo();
var result = Network.InitializeServer(32, parseInt(ServerPort), false);
if (result.ToString() != "NoError") {
var error = result.ToString();
Debug.Log(error);
if (error == "CreateSocketOrThreadFailure") error = "Already hosting!\n(Port in use:"+ServerPort+")";
ErrDialog(error);
}
}
function resetPlayerInfo(){
server_playerList = new Array();
server_guidList = new Array();
shared_playerList = new Array();
totalPlayers = 0;
}
//we add the name to the list but also the guid to keep track..
function addToPlayerList(nm:String, guid:String){
//addLog("NAME:"+nm+" GUID:"+guid);
server_playerList.Push(nm);
server_guidList.Push(guid);
totalPlayers++;
updateList();
}
//since on dc we dont know the name we can find the entry using the guid
function removeFromPlayerList(guid:String){
var index;
for(var i:int=0;i<server_guidList.length;i++) {
if (server_guidList[i] == guid) index = i;
}
server_playerList.Splice(index, 1);
server_guidList.Splice(index, 1);
totalPlayers--;
updateList();
}
//[SHOUT] the list of players .. send a string to everyone (s&c) with all player names separated by "|"
function updateList(){
var plist = "";
for(var i:int=0;i<server_playerList.length;i++) {
if (i > 0) plist += "|";
plist += server_playerList[i];
}
networkView.RPC("SVCL_PlayerList", RPCMode.All, plist);
}
//[LISTEN] for new client names
@RPC
function SV_AddPlayer(PN:String){
if (!Network.isServer) return; //prevents clients from executing this
var playerInfo = PN.Split("|"[0]);
addToPlayerList(playerInfo[0], playerInfo[1]); //add client player to list
}
//SERVER ONLY trigger (server start)
function OnServerInitialized(){
//addLog("SERVER CONNECT:"+PlayerName);
addToPlayerList(PlayerName, Network.player.guid); //add server player to list
}
//SERVER ONLY trigger (player DC)
function OnPlayerDisconnected (aPlayer:NetworkPlayer){
//addLog("DC player: " + aPlayer.guid);
removeFromPlayerList(aPlayer.guid); //remove clients that leave or drop
//Network.RemoveRPCs(aPlayer);
//Network.DestroyPlayerObjects(aPlayer);
}
/////////////////////////////////////////////////////////////////////////////
// CLIENT SIDE FUNCTIONS
/////////////////////////////////////////////////////////////////////////////
//CLIENT ONLY (client join)
//[SHOUT] your name to the server
function OnConnectedToServer(){
//addLog("SV_AddPlayer:"+PlayerName);
networkView.RPC("SV_AddPlayer", RPCMode.All, PlayerName+"|"+Network.player.guid);
}
//CLIENT ONLY (client join fail)
function OnFailedToConnect(error: NetworkConnectionError) {
Debug.Log("Could not connect to server: "+ error);
ErrDialog("Could not connect to server: "+ error);
}
/////////////////////////////////////////////////////////////////////////////
// COMMON FUNCTIONS
/////////////////////////////////////////////////////////////////////////////
//[LISTEN] for entire player list
@RPC
function SVCL_PlayerList(PL:String){
shared_playerList = PL.Split("|"[0]);
}
//CLIENT + SERVER (dc) (documentation sais this is client only but tests show it also triggers on server)
function OnDisconnectedFromServer (info:NetworkDisconnection){
if (Network.isServer) {
//ErrDialog(info.ToString());
Debug.Log("Local server connection disconnected");
resetPlayerInfo();
} else {
if (info == NetworkDisconnection.LostConnection){
ErrDialog("Connection lost.");
Debug.Log("Connection lost.");
} else {
if (!selfDC) ErrDialog("Host left the game.");
if (!selfDC) Debug.Log("Host left the game.");
}
//Network.RemoveRPCs(Network.player);
//Network.DestroyPlayerObjects(Network.player);
}
}
EDIT: You could also create a player class and use the Generic list to store the array like so:
import System.Collections.Generic;
class Player {
var guid : String = "";
var name : String = "";
var otherStuff : int = 0;
function Player(guid:String, name:String, otherStuff:int){
this.guid = guid;
this.name = name;
this.otherStuff = otherStuff;
}
}
var playerList : List.<Player> = new List.<Player>();
var tplayer:Player = new Player("123", "456", 789);
playerList.Add(tplayer);
EDIT2 The above stuff works but its not really how you do it proper. I found this guy showing the right way https://www.youtube.com/watch?v=7NcWnTInupE
Your answer
Follow this Question
Related Questions
Unity networking tutorial? 6 Answers
Network how to send data/activate function 1 Answer
RPCMode.Server works in one spot but not another 0 Answers
ClientRpc not called on Client 1 Answer
Networking: Players being "Perma-hit" 0 Answers