FPS Networking Problem

You have all probably seen this question posted a thousand times and so have I but I can seem to find anything that works. I have tried using networkView.isMine, but nothings seems to solve it so here is the problem. So basically the Connect and Start Server functions are working but when a player contains it obviously spawns the player object but one player seems to control both objects. Another problem I am having is when the first person creates the server it all works well but when a second person connects you see the camera view from the second player.

It is starting to become quite frustrating as I have spent the last couple of days trying to get this working but nothing seems to crack it. I am using the First Person Controller prefab included in Unity’s standard assets. If anyone could provide any input into this I would be truly grateful.

How are you handling spawning? In what function are the player prefabs spawned for each player, and are you using Network.Instantiate?

There is an empty gameobject called spawn so when the player connects or the server is started the Spawn script spawns a player prefab. Yes I am using Network.Instantiate.

So you’re calling Spawn() (or whatever you call it) in your spawn script in OnServerInitialized() and OnConnectedToServer()? eg: (simplified)

OnServerInitialized(){
	spawnScript.Spawn();
}

OnPlayerConnected(){
	spawnScript.Spawn();
}

//SpawnScript
Spawn(){
	Network.Instantiate(playerPrefab);
}

Yes basically but I don’t understand how you give one player ownership over their character.

You have to send an rpc to the spawned user and tell him he’s the owner of the object.
A user should have the script that moves the object disabled till he gets the rpc from the server telling him he’s the owner and then enable it
if the server spawns all objects, the server is the owner and not the players. so networkView.isMine won’t work

Sorry if I am a little dumb but I am pretty new to this stuff, so how do you send an RPC?

Well basically doesn’t really cut it, hehe :slight_smile: are you using those functions or not? What does your code look like?

EDIT: whoops, in that last post I meant to say OnConnectedToServer(), not OnPlayerConnected().

Network.Instantiate() is really a dressed up buffered RPC function… the player that calls it across the network will automatically own all the networkViews on the prefab that is instantiated (if it has them). OnServerInitialized() is only called by the player who created the server, as soon as the server is created, so that will create his prefab, and set up his networkViews. OnConnectedToServer() is called once on each client locally as soon as they connect to the server, so they each need to call Network.Instantiate() in there, so they each get their prefab set up. This way, ultimately every player has called their own Network.Instantiate() once, so they each have their own prefab with networkViews set up.

Once thats done, the best practice is to have a script on the player prefabs that enables/disables any scripts that that should or should not be running, depending on ownership, eg:

//PlayerNetworkInit

function OnNetworkInstantiate(){
	if(!NetworkView.isMine){ //if this isn't my prefab
		GetComponent('FPSInputController').enabled = false;
	}
}

Okay this is my spawn code, also the code you gave me above would have to make a new script and attach to the player prefab?

var player : Transform;
var remote : Transform;

function OnServerInitialized ()
{
	Network.Instantiate(player, transform.position, transform.rotation, 0);
}

function OnPlayerConnected ()
{
	Network.Instantiate(remote, transform.position, transform.rotation, 1);
}

I don’t actually know why I am using two separate prefabs. I added your code and I can control one without the other one moving but I am running two windows testing my game and one of the controllers will not move at all.

See my last post, I meant to say OnConnectedToServer(), not OnPlayerConnected(). (OnPlayerConnected() is called on the server whenever a client connects, so in this case, the server would own all prefabs).

Yeah, I probably wouldn’t use separate prefabs hehe.

in your case the server spawns the players ( authoritative ), so the server needs to get all inputs from the players, move the objects and update the players. You can create a reference to the instantiated object’s networkview and send an rpc.

var newPlayer = Network.Instantiate(player, transform.position, transform.rotation, 0);
newPlayer.networkView.RPC(…

Okay that makes things a little clearer, I better get scripting.
Thanks again

One last thing what do you do about the cameras on each prefab, as this seems to be causing a few problems do you just disable them by using

if(!networkView.isMine)
{
GetComponent(Camera).enabled = false;
}

Well if your using the standard FPS controller prefab, Camera is not a component on the top level of the prefab, its on a GameObject parented to the prefab. You’ll either have to Find() it by name, or use GetComponentInChildren() to destroy/disable it.

Okay that has mostly fixed it, hopefully a bit of optimization should solve it.
Thanks

This is how I set up the players:

// GameManager.cs

public NetworkView playerPrefab;

public void Join ()
{
    Network.Instantiate (playerPrefab, spawnPoint.position, spawnPoint.rotation, 0).RPC ("OnInitialize", playerParameters);
}

// ...

// Player.cs

void Awake ()
{
    if (networkView.isMine)
    {
        camera.main.transform.parent = transform;
        camera.main.transform.localPosition = Vector3.zero;
        camera.main.transform.localRotation = Quaternion.identity;

        // More local player configuration...
    }
    else
    {
        Destroy (GetComponent<InputController> ());
        // Destroy other components which should only be present on local player

        // More remote player configuration...
    }
}


[RPC]
void OnInitialize (/*...*/)
{
    // Set up player team or similar
}

That would have made things a lot simpler lol I spent ages making a series of scripts connect networkView.isMine. I will keep that in mind for future reference.