Search Unity

How to change color of object so host/clients can view it?

Discussion in 'Multiplayer' started by stockhouse50, Jul 20, 2017.

  1. stockhouse50

    stockhouse50

    Joined:
    Apr 9, 2015
    Posts:
    14
    Hi, I am very new to the networking in Unity. I have players spawn in as the host and the rest as clients. They each spawn in using the same prefab but give each player their own color. Now when I try to spawn a flag into the game, each player can view it, but I cannot change the color of the flag for either the host or the clients.

    What are the steps needed to do this? and is this the correct line when trying to the change the color : Flag.GetComponent<Renderer>().material.color = flagColor; //flagColor set to Color.yellow ?

    Thanks.
     
    Last edited: Jul 20, 2017
  2. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    Send a message to the server that instructs it to send a message to the clients that instructs them to change the color.
    Command and Rpc's are the way to go.
     
    Last edited: Jul 20, 2017
  3. stockhouse50

    stockhouse50

    Joined:
    Apr 9, 2015
    Posts:
    14
    Hi, I tried something like this where the GameManager calls a method from the script FlagSpawn which is attached to an empty Game Object called FlagSpawner, but it doesn't work. Neither line in the code -> Flag.GetComponent<Renderer>().material.color = flagColor; changes the color of the flag to yellow.

    [ClientRpc]
    public void RpcUpdateFlagColor()
    {
    Flag.GetComponent<Renderer>().material.color = flagColor; //flagColor set to Color.yellow
    }

    [Command]
    public void CmdSpawnFlag()
    {
    flagspot = Random.Range(0, m_flagSpawnPositions.Length / 2) * 2;
    Flag = Instantiate(Flag, m_flagSpawnPositions[flagspot].transform.position, Quaternion.identity) as GameObject;
    Flag.GetComponent<Renderer>().material.color = flagColor;
    NetworkServer.Spawn(Flag);
    RpcUpdateFlagColor();

    }
     
  4. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    You're saying this is on a GameManager? You need to read up on the documentation and/or the learning material. Commands can only be sent from objects that a client has authority over.

    But if I have missunderstood you. And the Command method is working, then I would like to know how / where you are setting the Flag object reference for the clients. You should probably just add a component to the flag with a syncvar. And then before actually Networking spawning it (Basically between the instantiation and the network spawn) you set the color in the SyncVar. Then make a syncvar hook or something alike that set's the color on Start and when the hook method is invoked.
     
  5. stockhouse50

    stockhouse50

    Joined:
    Apr 9, 2015
    Posts:
    14
    Hi, sorry I am trying to understand the networking from videos and reading documentation but some of the language is throwing me off. I guess to really understand this I have a few questions based on what you said.

    1) If I have a flag script and I have the GameManager spawn the flag. Will this be implicitly spawned on the server?

    2) Before the flag is spawned, can I declare and assign the flagColor like this in the flag script :

    [syncvar(hook=("UpdateFlagColor")]
    public Color flagColor;


    public void SpawnFlag(){

    flagspot = Random.Range(0, m_flagSpawnPositions.Length / 2) * 2;
    Flag = Instantiate(Flag, m_flagSpawnPositions[flagspot].transform.position, Quaternion.identity) as GameObject;
    flagColor = Color.yellow;
    NetworkServer.Spawn(Flag);
    }

    public void UpdateFlagColor(Color flagClr){
    Flag.GetComponent<Renderer>().material.color = flagClr;
    }

    Will that syncvar sync the flag color data to the clients?
     
  6. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    1. Depends, if with spawn you mean NetworkServer.spawn. Then no, it spawns on all clients. If you mean Instantiate. Then it's only on the server.
    2. Before you spawn it on the network but after you instantiate is a perfect time to set syncvars.
    3. And that code should probably work, except you are not ever updating the syncvar for the clients. But if you don't use any comparison it wont matter. But it's good practice to do.
     
  7. stockhouse50

    stockhouse50

    Joined:
    Apr 9, 2015
    Posts:
    14
    Ok, so in the GameManager after 2 players are added, then I spawn the flag like this -> GameObject.FindGameObjectWithTag("FlagSpawner").GetComponent<FlagSpawn>().SpawnFlag();

    Then in the FlagSpawn script I have this;

    [SyncVar(hook = ("UpdateFlagColor"))]
    public Color flagColor;

    public void UpdateFlagColor(Color flagClr)
    {
    Flag.GetComponent<Renderer>().material.color = flagColor;
    }

    public void SpawnFlag()
    {
    flagspot = Random.Range(0, m_flagSpawnPositions.Length / 2) * 2;
    Flag = Instantiate(Flag, m_flagSpawnPositions[flagspot].transform.position, Quaternion.identity) as GameObject;
    Flag.GetComponent<Renderer>().material.color = flagColor;
    flagColor = Color.yellow;
    NetworkServer.Spawn(Flag);
    UpdateFlagColor(flagColor);

    }

    Now on the host's screen there is a yellow flag, however the client's screen also shows a yellow flag but in a different spawn location and the same flag as the host's but with the default color of grey.Is it because I am not using a Command on SpawnFlag() that each client spawn's it own flag?

    Why would the same flag from the server show on the client, and not be yellow?
     
  8. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    Is the SpawnFlag method called on server or client?
     
  9. stockhouse50

    stockhouse50

    Joined:
    Apr 9, 2015
    Posts:
    14
    Well the GameManager script is attached to an empty object that is already in the scene when started and is the only script that calls SpawnFlag() with this line
    GameObject.FindGameObjectWithTag("FlagSpawner").GetComponent<FlagSpawn>().SpawnFlag();
    Just called in a regular method with no [Command], etc.

    This would lead me to believe it's called on the client then? If I have a script attached to a non-player object, how do I within that script spawn a non-player object onto the server if I can't use [Command]? Then use syncvars to send the info about the newly spawned non-player object to all of the clients, if that makes sense