In my game, each player controls a vehicle.
If their vehicle explodes, they can choose another one.
When a user picks a vehicle, the client calls a ServerPRC (to ensure that the user has enough vehicles left) and spawns it. BUT for some reason, it’s only appearing for the player who requested it (it should be showing for all)
I am using this to spawn the vehicle
[ServerRpc(RequireOwnership = false)]
private void RequestVehicleDeploymentServerRpc(ulong clientId, int vehicleId)
{
...
var newVehicle = Instantiate(vehicleSO.prefab, spawnPoint.transform.position);
newVehicle.GetComponent<NetworkObject>().SpawnAsPlayerObject(clientId);
...
}
I don’t fully understand player objects/ownership. My questions are:
- Does the ‘player object’ only spawn for that player? (it should spawn for everyone, but just one player can control it)
- More into ownership, what does ownership mean? does it mean THAT player has the right to move that object?
- should the player’s vehicle spawn on the client and send movement back to the server? or does the transform automatically send itself across the network
-should i be using newVehicle.GetComponent().SpawnWithOwnership(clientId) instead?
- an aside - what does RequireOwnership on the ServerRpc attribute do?
Player objects spawn for everyone, unless you change its network visibility.
Ownership means who can change network properties of an object. Normally the server owns everything except player objects. A script on a player object can use IsOwner to determine if it is the local player object. If a player object is not owned, it must be a remote player. The same is not true for general network objects (ie usable vehicles, carried items) as their ownership is handed over based on rules (owner == current driver / item wielder).
NetworkTransform defaults to server authoritative, you can subclass and override the authority property to make it client authoritative so a controlling player can directly change its transform values.
RequireOwnership means only an owner can call this rpc. For example if you have a NetworkTransform and pass the player‘s input to the server so that the server can verify and apply the input actions, it makes sense to restrict this action to owning players. Otherwise a remote player could accidentally control your local player.
Same for vehicle for instance. You only want the owner aka driver to be able to steer the vehice. Of course you could have a turret owned by a separate client who can then aim and fire the turret.
As to your issue, I have a hunch that you are despawning the player object when the vehicle gets destroyed. I wouldn‘t do that. Instead, keep the player object alive at all times. Then spawn a vehicle and assign the owner. When the vehicle spawns locally, it tells the player prefab instance that it has spawned so that you can take control of that vehicle (input could also be on the vehicle itself and only get enabled for the owner).
Your player prefab may only need to be a managing object that disables input on death or spawns new vehicles. This is how I implemented splitscreen multiplayer, where each player object isn‘t actually a player prefab but rather a separately spawned object that a player takes control over.
Ah thanks for clarifying the rules around ownership. Makes a lot of sense.
And furthermore, I believe i am destroying the previous player object and trying to spawn a new one. Very likely the issue. Which would explain why its not appearing. I’ll change the structure and report back. Thanks 
1 Like
Yep, swapping the logic around worked. Thanks.
Using one constant player object + spawning/destroying individually owned vehicles works.
Also makes it easy to do stuff like IsOwner
when checking for user input on a vehicle.
1 Like
Yup, once you get the hang of net-working it’s suddenly much less painful. 
But then you try to build a dedicated server and the game starts anew as you realize that IsServer is also true for the host and so on … 