Multiplayer Object spawned by client does not show up on host

I am creating a multiplayer strategy game in which each player can create units from a building. The player clicks on their building, then presses a key, and the unit appears.

I am currently doing multiplayer using the built-in unity networking (using HLAPI), and having it so one player is hosting the game, and the other player is not. If the player that is hosting the game spawns a unit, it appears on both players’ screens like it is supposed to, but if the client tries to spawn a unit, it will appear on their screen, but doesn’t appear on the other player’s screen. Which it should do. It seems like this must have something to do with code that runs correctly on the client but not the server, but I can’t figure out what is wrong despite trying things various ways.

This is my code for spawning the units. I have it attached to the building gameObject, where the units are spawned:

GameObject g = Instantiate (unitsSpawned ~~);~~

g.transform.position = transform.position;
PlayerScript.players[team].CmdSetAuthority(gameObject.GetComponent(), PlayerScript.players[team].GetComponent());
PlayerScript.players [team].CmdSpawnUnit (g);
PlayerScript.players[team] gets the player who owns the building, and these are the two command methods (in the Player class) I use:
[Command]
public void CmdSpawnUnit(GameObject unit) {
~~ NetworkServer.Spawn(unit);~~
}

[Command]
public void CmdSetAuthority(NetworkIdentity netId, NetworkIdentity playerID) {
~~ netId.AssignClientAuthority (playerID.connectionToClient);~~
}
The units I am spawning are prefabs with a NetworkTransform and a NetworkIdentity. I have tried both with and without local player authority checked, and neither of them work.
I know that the code for spawning the unit runs and spawns the unit locally, because the player who spawned the unit can see it, but the other player can only see it if it was the host player that spawned the unit, so something must be wrong with the networking.
I am using unity 5.4.1
Any ideas about what I am doing wrong would be really appreciated! Thanks!

On the prefab, make sure that on the NetworkIdentity (Script), Server Only is NOT checked - I don’t believe that ‘Local Player Authority’ should be checked either, try it with both unchecked.

Also, make sure that the unit prefab is registered in your network manager script! More details on the first code block of this page.

EDIT: The problem ended up being that you were trying to send a GameObject as a parameter in a [Command], which can only accept serializeable objects from simple data types such as integers, strings and floats, as well as Unity types such as Vector3 and user-defined structs.

One way to fix it would be to make a Dictionary of registered prefabs in the Spawner Building script with the unit name as the key and the GameObject prefab to spawn as the value, that way you can just write

PlayerScript.players [team].CmdSpawnUnit (g.name, PlayerScript.players[team].GetComponent<NetworkIdentity>());

and it’ll know what unit to spawn because the unit’s name is the same as the key in the Dictionary.