Intro
So this is a base model
that can be expanded to fit a number of multi-playered games that require the
users to take turns, such as board games, Jenga, Battleship, etc... In this
tutorial we're going to be making a "game" that allows for an infinite
number of players to connect and change the color of a central block when it is
their turn. 
1)    
Create a
flat plain, color it if you wish.
2)    
Create an
Empty GameObject and name it NetworkManager
a)    
Add the
component Network->(Network
Manager HUD)
3)    
Create an
empty GameObject, name it Player. Make it a prefab, delete from the Object
hierarchy. Even though the player won’t
have a physical body that they will be controlling, this step is necessary for
the NetworkManager to manage the players.
a)    
Give it a Network->NetworkIdentity Component.
b)    
Create
and attach the PlayerControllerScript to the Player Object.
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
using UnityEngine.UI;
public class PlayerController : NetworkBehaviour
{
    [SyncVar]
    public Color cubeColor;
    [SyncVar]
    private GameObject objectID;
    //determines
which player's turn it is
    [SyncVar]
    public int turn;
    //determines
which player the current player is
    public uint player;
    private NetworkIdentity objNetId;
    Text playerText;
    Text identityText;
    void OnDestroy()
    {
        GameStateManager.removePlayer((int)player);
    }
    void Start()
    {
        //The
network manager assigns network identities dynamically, 
        //so
just use this value as the current player's id
        player =  this.GetComponent<NetworkIdentity>().netId.Value;
        //add
player id to network
        GameStateManager.addPlayer((int)player);
        //get
the current turn
        turn = GameStateManager.getPlayerTurn();
        //initialize
player text, tells who's turn it is
        playerText = GameObject.FindGameObjectWithTag("PlayerTurnText").GetComponent<Text>();
        playerText.text = "It's working";
        //tells
you which player you are
        identityText = GameObject.FindGameObjectWithTag("IdentityText").GetComponent<Text>();
        identityText.text = "Player " + turn;
        identityText.color = new Color(Random.value, Random.value, Random.value, Random.value);
    }
    //
Update is called once per frame
    void Update()
    {
        if (isLocalPlayer)
        { 
            //checks
to see if the player clicked
            CheckIfClicked();
            //makes
sure that the player turn text is synced
            CmdGetTurn();
            changeTurnText();
        }
    }
    void CheckIfClicked()
    {
        if (Input.GetMouseButtonDown(0))
        {
            //update
the variable
            CmdGetTurn();
            //check
if it's my turn, if not, exit out
            if (turn != player) return;
            CmdChangeTurn();
            //change
the color
            objectID = GameObject.FindGameObjectsWithTag("Tower")[0];
            cubeColor = new Color(Random.value, Random.value, Random.value, Random.value);
            CmdChangeColor(objectID,
cubeColor);
        }
    }
    //updates
state on the server
    [Command]
    void CmdChangeTurn()
    {
        if (turn == player) GameStateManager.nextTurn();
        turn = GameStateManager.getPlayerTurn();
        //syncs
this all clients connected on server 
        RpcUpdateTurn(turn);
    }
    /*
    * Changes the turn text of the player
    */
    void changeTurnText()
    {
        if (turn == player)
            playerText.text = "Your turn. ";
        else if (turn != player)
            playerText.text = "Opponent's turn. ";
    }
    [ClientRpc]
    void RpcUpdateTurn(int i)
    {
        turn = i;
        changeTurnText();
    }
    [Command]
    void CmdGetTurn()
    {
        turn = GameStateManager.getPlayerTurn();   
    }
    [Command]
    void CmdChangeColor(GameObject go, Color c)
    {
        objNetId = go.GetComponent<NetworkIdentity>();
        objNetId.AssignClientAuthority(connectionToClient);
        RpcUpdateTower(go, c);
       
objNetId.RemoveClientAuthority(connectionToClient);
    }
    /*
     * Being sent from server to
     */
    [ClientRpc]
    void RpcUpdateTower(GameObject go, Color c)
    {
        go.GetComponent<Renderer>().material.color
= c;
    }   
}
4)    
Create a
Cube Object, and name it Tower. Make it a prefab and delete from the
hierarchy.
a)    
Give it a
Network->NetworkTransform. Ensure that the Transform Sync Mod is “Sync Transform”
5)    
Create an
empty object named TowerSpawnLoc, make it a prefab, delete from hierarchy.
6)    
Create an
empty object named GameManager
a)    
Create
and attach TowerSpawnLoc script to it
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
using System;
using UnityEngine.UI;
public class TowerSpawnLoc : NetworkBehaviour
{
    [SerializeField]
    GameObject towerPrefab;
    [SerializeField]
    GameObject towerSpawn;
    public override void OnStartServer()
    {
        SpawnTower();
    }
    void SpawnTower()
    {
        GameObject go = GameObject.Instantiate(towerPrefab, towerSpawn.transform.position, Quaternion.identity) as GameObject;
        NetworkServer.Spawn(go);
    }
}
i)
Add the
parameters, Tower Prefab->Tower, Tower
Spawn->TowerSpawnLoc
b)    
Create
and attach the GameStateManager
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
using System.Collections.Generic;
public class GameStateManager : NetworkBehaviour
{
    //an
enum, Player 1 = 1, Player 2 = 2.
    public static int playerTurn = -1;
    public static ArrayList connectedPlayers = new ArrayList(); 
    //call
this every time a player connects
    public static void addPlayer(int networkId)
    {
        connectedPlayers.Add(networkId);
    }
    //call
this every time a player disconnects
    public static void removePlayer(int networkId)
    {
        connectedPlayers.Remove(networkId);
    }
    public static int getPlayerTurn()
    {
        if (playerTurn == -1) playerTurn = (int)connectedPlayers[0];
        return playerTurn;
    }
    /*
     * Increment the player's turn
     */
    public static void nextTurn()
    {
        int currentIndex = connectedPlayers.IndexOf(playerTurn);
        if (currentIndex == connectedPlayers.Count - 1) playerTurn =
(int)connectedPlayers[0];
        else playerTurn = (int)connectedPlayers[currentIndex + 1];
    }
}
 
 
No comments:
Post a Comment