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. https://youtu.be/c5dOCmh2RMQ
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