I have worked myself into the new networking system, however I am having a problem, when I try to send a command, the console says: Tryin to send command for non-local player.
Basically what I want todo is have a “Player” ( just one ) controlled by multiple people ( the clients ).
I think the architecture of UNET won’t allow me todo this, since ( this is my understanding, please correct me if I am wrong ) a Player is a reserved gameobject, that “represents” a client and only via ones own player object can one send a command to the server. So with 2 clients I also need 2 player objects, if both of them want to send commands, right?
I also have a chat gameobject with a network identity and a script with the following code:
I just want to send a message to the server, that uses that message as a parameter on a Rpc, so every client can add that message to the UI ( AddMessage(…) ).
Can I even have scripts with commands, that are not placed on the player object?
A client definitely needs to have a player gameobject in order to send commands, is this right? Then maybe I can just create the player gameobject without having it visible on screen, and the “player”, that shall be controlled by the clients will be a different game object.
Hope it’s not too confusing, thanks for your time.
Jan
EDIT: Maybe just some more text. I don’t really get why the player game object is the representation of the client ( I know there’s also NetworkPlayer etc. ), what if a player dies and I destroy the object or what if it’s a strategy game and a player controls many different units, that I want to tag as “Player”? Will there then be a hidden player game object ( just for sending the commands etc… ) ?
In that case I would have a “empty” gameobject for each player, handling all the input data and sending it via Commands.
On the server I would spawn a regular gameobject.
Then, add the logic to get all the data received by the client controlled objects and apply it to the server object.
From there on, use SyncVars, ClientRPCs, NetworkTransform or custom implementation to get the “player” object synched properly on the clients in whatever way needed.
This is where I’m stuck in. The server does not see the client’s spawned object, even if I made the client to send a [Command] over to the server, telling the server to spawn in that client’s spawned object in.
This sounds like you’re doing your own implementation without HLAPI?
Otherwise you normally simply inherit from NetworkManager and override some event functions to adjust them to your needs.
The Client should never spawn itself, it should only REQUEST a spawn.
All the spawn work should be directed by the server - this makes the archtiecture clearer and is more secure (think of cheating).
Client side - request player spawn:
//dummy code if inheriting from NetworkManager
OnClientConnect
{
ClientScene.Ready…
//now request spawn
ClientScene.AddPlayer…
}
Server side - catch request from client and trigger synchronized spawn:
//dummy code if inheriting from NetworkManager
OnServerAddPlayer
{
//create object instance
GameObject player = GameObject.Instantiate…
//now spawn it on all clients
NetworkServer.AddPlayerForConnection…
//now add code to add new player gameobject to some static list
MyList.Add(player)
}
Some Server Spawned Object Script:
//first add prefab of this gameobject to NetworkServer spawnable object list in editor
GameObject obj = GameObject.Instantiate…
NetworkServer.Spawn…
Update routine
//go through static list (InheritedNetworkManagerBehaviour.MyList)
//get script with Command implementation for each client
//grab any data you need
//apply whatever needs to be done for each client to this single gameobject
I did not know that. In fact, I did not know I have to inherit Network Manager to make it fit my needs. Thank you for your pseudo-code. It showed a whole door to me. Back to reading the docs, I guess.
If any future questions regarding Network Manager and HLAPI implementation of RTS game modes, I will ask them in a different thread.
What I do now is I renamed my player to “Character”, which is the game object, that shall be controlled by all the clients.
I now have another gameobject Player, that checks for input etc. and sends commands, it has no visible representation in the game, it’s just the gameobject used to send commands etc. now. Every client has its own player gameobject now ( auto created with the network manager ).
This works so far, I have also noticed that there are mutliple player gameobjects ( one for each client ) and one can only send commands with the local player object, so I have to use “isLocalPlayer” in the function, that checks for user input.
I also have implemented a chat, since commands can only be send by the (local) player object, I have to put these commands in the script, that is used by the player object, right?
What I haven’t tried yet, so should work I guess, is to delegate things to the local player object, so in my chat script ( that’s not on the player game object ) I will have a reference to the local player game object and call methods its methods, which will then send commands.
At least I think I have understood the architecture now, though I don’t really know why there has to be multiple player game objects ( one for each client ) when only the local one is necessary to send commands, my guess is that they are needed for the RPCs, so each client has a corresponding player game object in the game of other clients.