Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Sheepers · Feb 20, 2017 at 07:37 PM · unity 5networkingmultiplayernetworkmultiplayer-networking

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 [s]);
 g.transform.position = transform.position;
 PlayerScript.players[team].CmdSetAuthority(gameObject.GetComponent<NetworkIdentity>(), PlayerScript.players[team].GetComponent<NetworkIdentity>()); 
 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!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by MarshallN · Feb 20, 2017 at 08:27 PM

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.

Comment
Add comment · Show 16 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image MarshallN · Feb 20, 2017 at 08:31 PM 0
Share

I think that if "Local Player Authority" is checked, you need to not just Spawn(), but SpawnWithClientAuthority(), explained at the bottom of the link I posted :)

avatar image Sheepers MarshallN · Feb 21, 2017 at 01:13 AM 0
Share

I tried SpawnWithClientAuthority as well, and that didn't work either.

avatar image MarshallN Sheepers · Feb 21, 2017 at 01:20 AM 0
Share

Just to make sure, the building GameObject that spawns the units doesn't have "Server only" checked on its NetworkIdentity, right?

Show more comments
Show more comments
avatar image Sheepers MarshallN · Feb 21, 2017 at 04:07 PM 0
Share

Ok, those print statements were actually very informative, thanks!

For the player whose units didn't work, it was trying to do the CmdSetAuthority on Null. For the player whose unit transferred correctly, it was not null.

avatar image MarshallN Sheepers · Feb 21, 2017 at 04:09 PM 0
Share

Sure thing!

Show more comments
Show more comments
avatar image Sheepers MarshallN · Feb 23, 2017 at 05:03 PM 0
Share

Ok, so while that looks like it might be more correct, it still doesn't fix the underlying problem that the spawning command is getting passed in a null gameObject.

avatar image MarshallN Sheepers · Feb 23, 2017 at 06:20 PM 0
Share

I'd hoped it was a null NetworkIdentity connection, rather than a null GameObject. Can you post the exact error you're getting?

Show more comments
Show more comments
avatar image Sheepers · Feb 20, 2017 at 09:43 PM 0
Share

@$$anonymous$$arshallN I tried it without local player authority on the objects, and nothing changed. The unit prefab is registered in the network manager.

avatar image Sheepers · Feb 24, 2017 at 12:32 AM 0
Share

Ok, but that couldn't be the problem. Here is my code:

 GameObject g = Instantiate (unitsSpawned [s]);
 g.transform.position = transform.position;
 print ("Spawning unit  " + g.ToString ());
 PlayerScript.players [$$anonymous$$m].CmdSpawnUnit (g, PlayerScript.players[$$anonymous$$m].GetComponent<NetworkIdentity>());            PlayerScript.players[$$anonymous$$m].CmdSetAuthority(g.GetComponent<NetworkIdentity>(), PlayerScript.players[$$anonymous$$m].GetComponent<NetworkIdentity>());
 

I am printing out exactly the same thing I am passing in, and in this print, it is not null, and in the print inside of the command, it is. So it can't be a problem with the original object, because it isn't null in this code.

avatar image MarshallN Sheepers · Feb 24, 2017 at 01:00 AM 0
Share

Oh dude, I found your issue. From the documentation, "SyncVars can be basic types such as integers, strings and floats. They can also be Unity types such as Vector3 and user-defined structs, but updates for struct SyncVars are sent as monolithic updates, not incremental changes if fields within a struct change. There can be up to 32 SyncVars on a single NetworkBehaviour script - this includes SyncLists."

[Command]s and [ClientRPC]s use the same data types as SyncVars - thus, you're trying to serialize a non-serializeable object, GameObject g. One way to fix it would be to make a Dictionary of registered prefabs with the unit name as the key and the GameObject to spawn as the value, that way you can just write

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

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

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

6 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to write a multiplayer game that uses a dedicated server? 0 Answers

Unity networking tutorial? 6 Answers

Pushed back when applying NetworkTransform 1 Answer

Unity relay server without matchmaking 0 Answers

UNet - Connecting and Testing a 'choose your character' scenario 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges