- Home /
Question by
Braveheart · Sep 15, 2012 at 02:55 AM ·
networkingmultiplayer
Server instantiated player objects aren't controllable by the client instead by the server
Hello
In the code below I have the server instantiate a player prefab whenever a player connects. Once everything has been set-up I then send an RPC to all connected clients buffered and if a connected client owns any of these prefabs, they take control of it. However what happens when a player connects is the server takes control of the object and the client is left with the default view. If multiple clients connect, the server can move all of those objects.
Why is this happening?
The code:
Server.cs
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Server : MonoBehaviour {
private Rect serverDisWindowRect;
private int serverDisWindowWidth = 300;
private int serverDisWindowHeight = 150;
private int serverDisWindowLeftIndent = 10;
private int serverDisWindowTopIndent = 10;
private int numberOfPlayers = 200;
private string url = REMOVED;
private string faction;
private string spawnPoint; // From mySQL
public Transform player; // Player Prefab
private GameObject[] spawnPoints;
public List<PlayerScript> playerScripts = new List<PlayerScript>();
void Start () {
Network.InitializeSecurity();
Network.InitializeServer(numberOfPlayers, 25199, !Network.HavePublicAddress());
}
void OnPlayerConnected(NetworkPlayer networkPlayer){
Debug.Log (Persist.CharacterName + " connected");
SpawnPlayer(networkPlayer);
}
void OnServerInitialized() {
Debug.Log("Server up and running!");
}
void SpawnPlayer(NetworkPlayer networkPlayer) {
// Find all spawn points and place a reference to them in the array
// spawnPoints then randomly select one for spawning (spawn points
// to be placed at default spawning area. e.g. Airport arrivals terminal)
//if mySQL doesn't already hold a custom spawn point, then use the default ones
spawnPoints = GameObject.FindGameObjectsWithTag("SpawnPoint");
GameObject randomSpawn = spawnPoints[Random.Range(0, spawnPoints.Length)];
// Have the server Instantiate the player
Transform playerTrans = Network.Instantiate(player, randomSpawn.transform.position,
randomSpawn.transform.rotation, 0) as Transform;
NetworkView playerNetworkView = playerTrans.networkView;
PlayerScript playerScript = playerTrans.GetComponent<PlayerScript>();
playerScripts.Add(playerScript);
playerScript.owner = networkPlayer;
playerNetworkView.RPC("SetPlayer", RPCMode.AllBuffered, networkPlayer);
}
void OnPlayerDisconnected(NetworkPlayer networkPlayer) {
Debug.Log("Username: " + Persist.Username + " / Character: " + Persist.CharacterName + " disconnected");
//UPDATE MYSQL WITH POSITION DATA
CharacterUpdate();
Network.RemoveRPCs(networkPlayer);
Network.DestroyPlayerObjects(networkPlayer);
}
#region CharacterUpdate()
void CharacterUpdate() {
WWWForm form = new WWWForm();
form.AddField("username", Persist.Username);
form.AddField("character", Persist.CharacterName);
form.AddField("password", Persist.pa);
WWW www = new WWW(url, form);
StartCoroutine(updateChar(www));
Debug.Log("Character " + Persist.CharacterName+"'s information being updated");
}
IEnumerator updateChar(WWW www)
{
yield return www;
if (www.error == null)
{
Debug.Log(Persist.CharacterName+"'s information updated! Response: " + www.text);
//Response = www.text;
www.Dispose();
} else {
Debug.Log("Database connection error: "+ www.error);
www.Dispose();
}
}
#endregion
void Update () {
}
void ServerDisconnectWindow(int windowID) {
GUILayout.Label("Number of players online: " + Network.connections.Length);
if(Network.connections.Length >= 1) {
GUILayout.Label("Average ping: " + Network.GetAveragePing(Network.connections[0]));
}
if(GUILayout.Button("Shutdown server")) {
Network.Disconnect();
Application.Quit();
}
}
void OnDisconnectedFromServer(NetworkDisconnection info) {
Application.Quit();
}
void OnGUI() {
if(Network.peerType == NetworkPeerType.Server) {
serverDisWindowRect = new Rect(serverDisWindowLeftIndent, serverDisWindowTopIndent,
serverDisWindowWidth, serverDisWindowHeight);
serverDisWindowRect = GUILayout.Window(1, serverDisWindowRect, ServerDisconnectWindow, "");
}
}
#region Server Interface
#endregion
}
PlayerScript.cs
using UnityEngine;
using System.Collections;
/// <summary>
/// This script will contain the player's main movement control, all to be sent to the
/// server for a decision on new position to be made. The client should be allowed to control
/// themselves client side too to avoid choppiness whilst waiting on the server's response
/// </summary>
public class PlayerScript : MonoBehaviour {
public NetworkPlayer owner;
void Start () {
if (Network.isClient)
{
enabled = false;
}
}
[RPC]
void SetPlayer(NetworkPlayer player)
{
owner = player;
if (player == Network.player)
{
enabled = true; //Reenable this script if the object is ours
}
}
// REST TO BE WRITTEN...
}
Comment
Your answer
Follow this Question
Related Questions
Unity networking tutorial? 6 Answers
[Networking]How to call a command function from a UI element(a button) 2 Answers
Networking Player Nametag 1 Answer
Client can't spawn GameObject's 0 Answers