Search Unity

Question How to customize players?

Discussion in 'Netcode for GameObjects' started by KristenBoyGames, May 14, 2022.

  1. KristenBoyGames

    KristenBoyGames

    Joined:
    May 23, 2021
    Posts:
    38
    I have two scripts one on the player prefab and the other on the GameController and the goal is to let players have costum skins and i have been trying to do it but with no luck the script on the GameController goes like this
    Code (CSharp):
    1.     [ClientRpc]
    2.     public void SetMatOfOtherPlayersClientRpc(int playerid, int mat)
    3.     {
    4.  
    5.         GameObject.Find("GameController").GetComponent<GameController>().players[playerid].GetComponent<Renderer>().material = materialslist[mat];
    6.         Debug.LogError(playerid+"          "+mat);
    7.  
    8.     }
    9.  
    10.     [ServerRpc]
    11.     public void GetMatOfOtherPlayersServerRpc(int playerid, int mat)
    12.     {
    13.         SetMatOfOtherPlayersClientRpc(playerid, mat);
    14.        
    15.     }
    and the script on the player prefab goes like this
    Code (CSharp):
    1.     public void UpdateMatForOtherPlayers()
    2.     {
    3.         GameObject.Find("GameController").GetComponent<MaterialScript>().
    4.             GetMatOfOtherPlayersServerRpc((int)NetworkManager.Singleton.LocalClientId, PlayerPrefs.GetInt("SavedCurrentMat"));
    5.     }
    i dont know why it doesnt work nor how to do it any other way
     
  2. KristenBoyGames

    KristenBoyGames

    Joined:
    May 23, 2021
    Posts:
    38
    i think i know how to make it work, i added a int list of materials and a int list of playerids and the idea is that everyone writes their id and the mat they want to them and then a loop applies them, but the lists wont sync, they will only ever have the owners id and mat in it
    Code (CSharp):
    1.  
    2.     [ClientRpc]
    3.     public void SetMatOfOtherPlayersClientRpc(int playerid, int mat)
    4.     {
    5.         if (!playerids.Contains(playerid))
    6.         {
    7.             playerids.Add(playerid);
    8.             mats.Add(mat);
    9.         }
    10.         for (int i = 0; i < playerids.Count; i++)
    11.         {
    12.             GameObject.Find("GameController").GetComponent<GameController>().players[playerids[i]].GetComponent<Renderer>().material = materialslist[mats[i]];
    13.         }
    14.     }
    15.  
    16.     [ServerRpc]
    17.     public void GetMatOfOtherPlayersServerRpc(int playerid, int mat)
    18.     {
    19.         SetMatOfOtherPlayersClientRpc(playerid, mat);
    20.         if (!playerids.Contains(playerid))
    21.         {
    22.             playerids.Add(playerid);
    23.             mats.Add(mat);
    24.         }
    25.     }
     
  3. KristenBoyGames

    KristenBoyGames

    Joined:
    May 23, 2021
    Posts:
    38
    also if there is any easier way to do it, let me know
     
  4. ClearDark

    ClearDark

    Joined:
    Aug 25, 2013
    Posts:
    14
    For my prototype, I apply a random color on the material on each spawned player. The way I do this is like so:

    I have a NetworkVariable type of Vector3 on the Player controller, once the player is connected I call a server rpc that sets the value of that variable to a random color, after thats done the function calls a client rpc that sets the local transform material color to the one set by the server.

    On the player controller update function, i keep setting the material color to the network variable color set by the server,

    here's a lobby with 7 players connected, all have same prefab, with server assigned random color
     

    Attached Files:

    • sam.png
      sam.png
      File size:
      181.7 KB
      Views:
      197
  5. KristenBoyGames

    KristenBoyGames

    Joined:
    May 23, 2021
    Posts:
    38
    But how do i make it so the server sets it to the color the client wants?
     
  6. ClearDark

    ClearDark

    Joined:
    Aug 25, 2013
    Posts:
    14
    You call a server rpc from the client with the color you want the server to set.
     
  7. KristenBoyGames

    KristenBoyGames

    Joined:
    May 23, 2021
    Posts:
    38
    ok so i did it like this
    Code (CSharp):
    1.     public void UpdateMatVarServerRpc()
    2.     {
    3.         currentmats.Value = PlayerPrefs.GetInt("SavedCurrentMat");
    4.         Debug.Log("Currentmats.value set to" + PlayerPrefs.GetInt("SavedCurrentMat"));
    5.         GameObject.Find("GameController").GetComponent<MaterialScript>().setMatOnJoinClientRpc();
    6.     }
    this is called by the client on the client playerObject
    Code (CSharp):
    1.     [ClientRpc]
    2.     public void setMatOnJoinClientRpc()
    3.     {
    4.      
    5.         for (int i = 0; i < GameObject.Find("GameController").GetComponent<GameController>().players.Count; i++)
    6.         {
    7.             GameObject.Find("GameController").GetComponent<GameController>().players[i].GetComponent<Renderer>().material =
    8.                 materialslist[GameObject.Find("GameController").GetComponent<GameController>().players[i].GetComponent<listOfMaterials>().currentmats.Value];
    9.  
    10.             Debug.Log("SetMatOnJoinClientRpc   " + GameObject.Find("GameController").GetComponent<GameController>().players[i].GetComponent<Renderer>().material.name
    11.                 + "      " +
    12.                 materialslist[GameObject.Find("GameController").GetComponent<GameController>().players[i].GetComponent<listOfMaterials>().currentmats.Value].name
    13.                 +"       "+
    14.                 GameObject.Find("GameController").GetComponent<GameController>().players[i].transform.position+"     "+i);
    15.          
    16.         }
    17.  
    18.     }
    and this is on the game controller and the problem with this is that all the playersobjects have the skin that localClient has

    so i assume that the problem is that the networkvariables are not different for every client, so that every client thinks that the networkVariable on other players has the same value of the localClients networkVariable
     
    Last edited: May 18, 2022
  8. ClearDark

    ClearDark

    Joined:
    Aug 25, 2013
    Posts:
    14
    You got the first part good. Now all you have to do is make sure every client updates every "player" object with the Network variable color, just call the update material method in the player controller Update method (not under IsOwner and IsClient conditionals, since you want ALL gameobjects for every client to update with their own respective colors),


    Here are some snippets from my prototype


    Code (CSharp):
    1.    
    2.     [SerializeField]
    3.     private NetworkVariable<Vector3> FresColor = new NetworkVariable<Vector3>();
    4.  
    5.  
    6. [ServerRpc]
    7.     public void UpdateColorServerRpc()
    8.     {
    9.         FresColor.Value = new Vector3(Random.Range(0f, 5f), Random.Range(0f, 5f), Random.Range(0f, 5f));
    10.         SetColorClientRpc(FresColor.Value);
    11.     }
    12.  
    13.     [ClientRpc]
    14.     public void SetColorClientRpc(Vector3 color)
    15.     {
    16.         Color background = new Color(
    17.          color.x,
    18.         color.y,
    19.          color.z, 1f
    20.         );
    21.  
    22.         if (IsClient && IsOwner)
    23.         {
    24.             this.transform.Find("Ganfaul").gameObject.GetComponent<Renderer>().material.SetColor("_GlowColor", background);
    25.         }
    26.     }


    Code (CSharp):
    1. void Update()
    2.     {
    3.         Color background = new Color(
    4.              FresColor.Value.x,
    5.              FresColor.Value.y,
    6.               FresColor.Value.z, 1f
    7.             );
    8.         this.transform.Find("Ganfaul").gameObject.GetComponent<Renderer>().material.SetColor("_GlowColor", background);
    9.  
     
  9. KristenBoyGames

    KristenBoyGames

    Joined:
    May 23, 2021
    Posts:
    38
    i dont know how but i managed to f this up
    Code (CSharp):
    1.  
    2.     [ServerRpc]
    3.     public void UpdateMatVarServerRpc()
    4.     {
    5.         currentmats.Value = PlayerPrefs.GetInt("SavedCurrentMat");
    6.         Debug.Log("Currentmats.value set to  " + PlayerPrefs.GetInt("SavedCurrentMat") +"   "+currentmats.Value);
    7.         setMatClientRpc(currentmats.Value);
    8.     }
    9.  
    10.     [ClientRpc]
    11.     public void setMatClientRpc(int mat)
    12.     {
    13.         if (IsClient && IsOwner)
    14.         {
    15.             gameObject.GetComponent<Renderer>().material = materialslist[mat];
    16.         }
    17.     }
    18.  
    19.  
    20.  
    this is what i ended up with and idk what it even does