Hello, I’m testing the UNET system trying to switch my game from the old one to the new one, but I’m having some troubles.
I already setup the server and the client with the network manager.
I’ve spawned the player prefab (this object will control other players prefabs)
There’s a point which I need to spawn an object from the player prefab (this object has a NetworkIdentity and the player will control that object).
If I use a [Command] function to send it to the server, then it works ok and it’s spawned everywhere.
The problem is if the object is created on the server the client does not have the authority so I cannot call Command functions.
Another problem is the instantiated gameobject is not destroyed when the player disconnects.
Anyone got an answer to this? If a server spawns an object, how can the client call a function on one of its scripts?
I have a building that is placed by CmdSpawnBuilding(). Any client/host can place a building that everyone sees, but they can’t run any of its functions afterwards, even commands.
Edit: You have to send the NetworkInstanceId of the object to the server. Get it from the object’s NetworkIdentity component. Then the server can call whatever function you wanted on the gameobject.
Your avatar sends message to his avatar (on your computer), and his avatar forwards message to server. Server’s reaction is returned to his avatar on both of your computers.
Your avatar sends message about his avatar to server, and server processes this message. The server returns new state of his avatar to both of your computers.
Either way the authoritative server can verify messages from your computer.
But I guess, the second way is more correct (although, first way is simpler). Yet, I have not reached this stage of my project yet.
I’m having same problem, but after a few hours, I found the solution. It’s not so easy.
First, a few notes:
Networking uses something called “player controller id”. It’s a number (type: short) which is used to identify what you want to spawn. It’s something like “spawned object type identificator”. Value 0 (zero) is default, but all other values are free to use.
Note: it doesn’t mean you can use only one prefab per single player controller id. You can select the prefab, send info about selected prefab to server through command (identify it with number, string or anything else which can be sent by command) and then use a player controller id (for example “1”) to ask server to spawn the selected prefab.
In my system, I need to use something I call “default local player”. It’s instance of a prefab which was configured in NetworkManager class in field “Player Prefab” spawned by this very NetworkManager. From all players instances, the “local” one is the one representing (and controlled by) local player.
My how-to:
Define an ID for prefab type you want to spawn. This ID is player controller id I talked about above. In my example, I use number one.
Derive a class from NetworkManager and override OnServerAddPlayer method. (Deriving from NetworkManager is purely because of the Add Player message - if you want to, you can use
NetworkServer.RegisterHandler, but I found my way easier).
public override void OnServerAddPlayer(NetworkConnection conn,
short playerControllerId)
{
if(playerControllerId == 0)
{
// For default type use default implementation
// (spawnes prefab configured in inspector)
base.OnServerAddPlayer(conn, playerControllerId);
}
else if(playerControllerId == 1) // (Used 1 as id of my prefab type)
{
NetworkServer.AddPlayerForConnection(conn,
Instantiate(MyOtherPrefab), playerControllerId);
}
}
MyOtherPrefab is the prefab I want to spawn. This method spawnes the prefab on client request.
Clients request spawning with ClientScene.AddPlayer() method. This method requires an instance of NetworkConnection. I’m really not sure where to take it “correctly”, so I use default local player instance.
However this won’t work for client who is also a host. But for this special case, you can call NetworkServer.AddPlayerForConnection or NetworkManager.OnServerAddPlayer directly;
Networking: Added support for client-side authority for non-player objects.
The new function NetworkServer.SpawnWithClientAuthority(GameObject obj, NetworkConnection conn) allows authority to be assigned to a client by its connection when an object is created. This would typically be used in a command handler for a client asking to spawn an object, then the client’s connection would be passed in. For example:
[Command]
void CmdSpawn()
{
var go = (GameObject)Instantiate(otherPrefab, transform.position + new Vector3(0,1,0), Quaternion.identity);
NetworkServer.SpawnWithClientAuthority(go, base.connectionToClient);
}
For setting the authority on objects after they are created, there are the new functions AssignClientAuthority(NetworkConnection conn) and RemoveClientAuthority(NetworkConnection conn) on the NetworkIdentity class. Note that only one client can be the authority for an object at a time. On the client that has authority, the function OnStartAuthority() is called, and the property hasAuthority will be true.
The set of objects that is owned by a client is available in the new property NetworkConnection.clientOwnedObjects which is a set of NetworkInstanceIds. This set can be used on the server when a message is received to ensure that the client that sent the message actually owns the object.
When a client disconnects, the function DestroyPlayersForConnection now destroys all the objects owned by that connection, not just the player object. Objects which have their authority set to a client must have LocalPlayerAuthority set in their NetworkIdentity.
Networking: Added support for network [Command] calls from non-player objects with authority on a client. Since in 5.2 clients can have authority over non-player objects using NetworkServer.SpawnWithClientAuthority() or NetworkIdentity.AssignClientAuthority(), network Commands were extended from being allowed from just the player object to any object that is controlled by a client
I just want my client to spawn a object but it is not spawning on Server. I have Unity pro and I am spawning it with NetworkServer.SpawnWithClientAuthority(), but no success. @seanr
The event indicates the client must send a message with instructions to the server.
Client sends the message to the server.
Server receives the message.
Server begins processing the message.
Server sees that the message indicated the client wants a new object to be spawned.
Server sends to the client, as well as all other clients that are listening to this message, a new message with new instructions.
Each listening client receives the server’s message.
Each listening client processes the server’s message.
Each listening client sees the server wanted to spawn a new object for a particular client.
Each listening client instantiates a new object.
Each listening client assigns the ownership of the new instantiated object to that particular client.
Each listening client now understands whom the new instantiated object belongs to.
Each listening client handles the newly instantiated object accordingly.
TLDR; Client A sends a message to Server, telling the Server to send back a message to all clients A through Z that a new object is about to spawn, and that object belongs to Client A.
Only the server can assign authority so really, the client just needs to send a request to the server to spawn the thing. Then the server can spawn the thing in question and use that client’s NetworkConnection as the one to assign authority to.
Unet was deprecated a year ago, you should really be moving on instead of churning up old threads about stuff that is removed from the current scripting reference. But since no one seems to listen, put the below on the Player GameObject.
The big problem is that there is nothing out there to safely implement all the other stuff, that I’m using in my project. I would like to just go on vacation until everything is finally ready to use. This is not gonna happen, though…
I feel the same way. I don’t want to use UNET because of its deprecation, however, the new multiplayer system isn’t ready yet. So I’m probably going to stick with singleplayer and local multiplayer games for now, at least until the new multiplayer system is ready.
Unity now is on their 3rd networking implementation. Both previous times they were released half baked with little follow up. Unity has said or done nothing to indicate that this round will be handled differently, and past behavior says you shouldn’t be waiting breathlessly for what Unity releases for networking. Especially when networking isn’t a feature that even needs an implementation from Unity directly.
They’ve been working a year on a system which looks like something someone knowledgeable in writing networking code could have built in a few weeks. Most of the blog posts on the topic focus on their monetized server hosting rather than the networking API. The networking API appears to me to not be a priority at Unity or it would have been fully featured and released months ago. Just go with a solution not from Unity.