Search Unity

Turn Based Multi-Player game, not controlling a character

Discussion in 'Multiplayer' started by dben41, Dec 9, 2015.

  1. dben41

    dben41

    Joined:
    Nov 12, 2015
    Posts:
    4
    Hello I'm new to Unity, but have experience in programming,

    1. I want to create a simple demo. I want there to be a cube, in the middle of a plane, that changes colors when you click it. (This was easy to implement)
    2. I want there to be two players, who take turns clicking the cube.
    3. The cube will only change colors if it is your turn. If the cube changes colors, the change will reflect on both the players' screens.
    I've been looking at the examples for UNET, http://forum.unity3d.com/threads/unet-sample-projects.331978/, and most of them have a networked character who you control with your keyboard, and this aspect is throwing me off. Do I still need to create 2 players, but just have them be invisible and have no control scripts? Should my block be a prefab? Here's my script for my block:

    Code (csharp):
    1.  
    2. void Update()
    3. {
    4.       if (Input.GetKeyDown(KeyCode.Space))
    5.       {
    6.           // Command function is called from the client, but invoked on the server
    7.            CmdChangeColor();
    8.        }
    9. }
    10.  
    11. [Command]
    12. void CmdChangeColor()
    13. {
    14.       if (cubeColor == Color.green) cubeColor = Color.magenta;
    15.       else if (cubeColor == Color.magenta) cubeColor = Color.blue;
    16.       else if (cubeColor == Color.blue) cubeColor = Color.yellow;
    17.       else if (cubeColor == Color.yellow) cubeColor = Color.red;
    18.       else cubeColor = Color.green;
    19.  
    20.       GetComponent<Renderer>().material.color = cubeColor;
    21. }
    22.  
    Also I'll note that my Block isn't currently a prefab. I have the Network Identity component enabled, as well as the network transform->Sync transform. When I start the server host, I'm able to change the color of the block, but the client can't view these changes. When the client clicks the block, nothing happens, except the error message: *Trying to send command to the object without authority.*

    Any help would be appreciated! Thank you
    http://docs.unity3d.com/Manual/UNetSetup.html

    **EDIT** I've thought that perhaps the code to control the cube needs to be in the player object? Like if the player clicks, then change the cube.
     
    Last edited: Dec 10, 2015
  2. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
    What I would think you'd want to look into is NetworkServer.ReplacePlayerForConnection() as well as NetworkIdentity.AssignClientAuthority(). I don't have the time to do all the heavy lifting for you, but my thought process is this...

    1. Have the NetworkManager auto-spawn some sort of Empty GameObject that can represent the player in the scene.
    2.a. When two players connect to the match, some how decide who goes first.
    2.b. Whoever goes first is who you need to NetworkIdentity.AssignClientAuthority() for. This will be done on the cube.
    2.c. Then you'll need to NetworkServer.ReplacePlayerForConnection(). This will swap the player from being in control of their Empty GameObject, to being in control of the Cube.
    3.a. After the player makes their "turn"...you need to use ReplacePlayerForConnect to switch that player back to their Empty.
    3.b. Then you need to AssignClientAuthority of the cube to the next player.
    3.c. Then you need to ReplacePlayerForConnection for the current player from THEIR Empty to the cube.
    4. Repeat steps 3.a through 4 until the game is over.
     
    dben41 likes this.
  3. dben41

    dben41

    Joined:
    Nov 12, 2015
    Posts:
    4
    Thank you for your response! It helped quite a bit to achieve my final desired outcome.
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using UnityEngine.Networking;
    5.  
    6. public class OnTouchEvent : NetworkBehaviour
    7. {
    8.     //this will get called when you click on the gameObject
    9.     [SyncVar]
    10.     public Color cubeColor;
    11.     [SyncVar]
    12.     private GameObject objectID;
    13.     private NetworkIdentity objNetId;
    14.  
    15.  
    16.     void Update()
    17.     {
    18.         if (isLocalPlayer)
    19.         {
    20.             CheckIfClicked();
    21.         }
    22.     }
    23.  
    24.     void CheckIfClicked()
    25.     {
    26.         if (isLocalPlayer && Input.GetMouseButtonDown(0))
    27.         {
    28.             objectID = GameObject.FindGameObjectsWithTag("Tower")[0];                         //get the tower                                  
    29.             cubeColor = new Color(Random.value, Random.value, Random.value, Random.value);    // I select the color here before doing anything else
    30.             CmdChangeColor(objectID, cubeColor);
    31.         }
    32.     }
    33.  
    34.    
    35.  
    36.     [Command]
    37.     void CmdChangeColor(GameObject go, Color c)
    38.     {
    39.         objNetId = go.GetComponent<NetworkIdentity>();        // get the object's network ID
    40.         objNetId.AssignClientAuthority(connectionToClient);    // assign authority to the player who is changing the color
    41.         RpcUpdateCube(go, c);
    42.         // use a Client RPC function to "paint" the object on all clients
    43.         objNetId.RemoveClientAuthority(connectionToClient);    // remove the authority from the player who changed the color
    44.     }
    45.  
    46.     [ClientRpc]
    47.     void RpcUpdateCube(GameObject go, Color c)
    48.     {
    49.         go.GetComponent<Renderer>().material.color = c;
    50.     }
    51.  
    52. }
    53.  
    54.  
     
  4. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
    Looks solid enough. Only thing is you don't need to check "isLocalPlayer" both in the Update and in the method. If "isLocalPlayer" is false, the method won't be called in the first place.