Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 11 Next capture
2021 2022 2023
1 capture
11 Jun 22 - 11 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 /
This post has been wikified, any user with enough reputation can edit it.
avatar image
1
Question by grandmapuckett · Jul 28, 2015 at 06:28 PM · unity 5networkingspawnunity multiplayer

Unet - NetworkServer.Spawn() correct usage

Hello, I am working on an RTS game: I have a gamelord class (attached to its own object) that is supposed to handle the status of the game, then i have a playerController class that handles player actions and is attached on the player prefab, which gets fed to the network manager and spawned correctly when a new client connects to the game. The idea would be to centralize all gameplay actions into the gamelord and separate all the local stuff that needs to happen to other classes.

The gamelord is "unique" in the sense that it's meant to hold the same information on each client, most of its variables are syncvars, and all of its functions are supposed to be things that should happen on the server and then echo on every client, so stuff like creating a unit or building , keeping track of winning/losing conditions, etc.

playerControllers on the other hand handle the local player's input and then translate that input into game actions by calling the appropriate functions on the gamelord. So if the player builds something, the playerController class would do something like "gamelord.Build(something)" and then the gamelord would actually instantiate and spawn that something.

So, in code, here is what i am trying to do

on the playerController :

 [Command]public void CmdCreateBuildingHere(Vector3 pos,GameObject what)
     {        
        //some other non-related code
         gameLord.SpawnBuilding(playerId, pos, what);
     }

then, on the gamelord

  [Server]
     public void SpawnBuilding(string owner,Vector3 where,GameObject what)
     {
         GameObject newBuilding = (GameObject) GameObject.Instantiate(what,where,Quaternion.identity);
         RTSGamePiece newbuildingCtrl = newBuilding.GetComponent<RTSGamePiece>();
         newbuildingCtrl.owner = owner;        
         NetworkServer.Spawn(newBuilding);
     }

This approach does not work, as it behaves correctly only on the host, while if the client builds something, it won't show on the server.

On the other hand, moving the SpawnBuilding() lines of code directly into the first function and forgetting about the gamelord does make it work, but architecturally it's not what i meant to do, and it seems less logical to give more weight to the player object in an RTS where the important objects are not the player objects (like in FPSes).

All the objects that i want to spawn are already registered in the netmanager (i did it manually via the editor, the prefab for the netmanager already contains all the prefabs it needs in the "spawn info" section), so that should not be the cause.

My question is: Considering the constraints of Unet (some of which i am aware, such as commands only working on playerObjs or prefab registering, and many of which i'm not) ,is there a way to do this in the way i wanted it to?

Specifically:in the client, have the playerController class calling a function in the gamelord, and then on the server have the gamelord actually instantiating the object and spawning it across the network.

Should i rethink my approach? Am i misusing Commands and the [Server] attribute? Is there something about NetworkServer.Spawn that i am missing?

Thank you for your time, Dario.

Comment
Add comment · Show 2
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 nisovin · Jul 28, 2015 at 07:46 PM 0
Share

Are your scripts are NetworkBehaviors and not $$anonymous$$onoBehaviors?

avatar image grandmapuckett · Jul 29, 2015 at 09:32 AM 0
Share

both of them inherit from NetworkBehaviour, yes

3 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by meat5000 · Jul 28, 2015 at 07:32 PM

Here's an example.

 @Command
 function CmdSpawnOnNetwork()
 {
     var myPattern = myGun.bulletPattern;
     var projectileObject = Instantiate(myGun.bulletType, Vector3(transform.position.x, transform.position.y, transform.position.z), transform.rotation * Quaternion.Euler(0, 180, 0));
     NetworkServer.Spawn(projectileObject);
     projectileObject.AddComponent(SwerveShot); 
 }

Notice its @Command (`[Command]` -C#) not @Server.

@Server specifies a function to run on server only.

The Command attribute is to invoke a method on a server from a client.

Spawn your object, hold its reference, use that reference to perform actions on that object. You seem to have done all this.

Just change [Server] to [Command] and make that one your Cmd function. If you want to call a function on a client only use [Client]

 @Client
 public function ShootButtonPress() :void
 {
     CmdSpawnOnNetwork();
 }

on a function or

 if(isClient)

within one.

Comment
Add comment · Show 4 · 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 meat5000 ♦ · Jul 28, 2015 at 07:38 PM 0
Share

In the above code, my Button press fires off the Client function which in turn invokes the Cmd Command function, which is the bit that does the networking stuff.

The object you spawn needs to be a registered prefab. If its not you can register it with ClientScene.RegisterPrefab or something like. I've never used it, yet. You can register a SpawnHandler for objects with no prefab

http://docs.unity3d.com/ScriptReference/Networking.ClientScene.RegisterSpawnHandler.html

avatar image nisovin · Jul 28, 2015 at 07:45 PM 0
Share

He did use [Command] in his code. The function that has [Server] was called from the one that already has [Command]. I'm not sure whether that [Server] tag is necessary, but I'm not sure if it's wrong either.

avatar image meat5000 ♦ · Jul 28, 2015 at 07:57 PM 0
Share

It didnt work did it? :D

avatar image grandmapuckett · Jul 29, 2015 at 09:43 AM 0
Share

All of the prefabs are registered already, so that's not the problem.

$$anonymous$$y problem is that the second function only gets called from the host's local client, and not from remote clients. If the host builds something, it does work and it does spawn across the network. If a remote client tries to, it won't work because the second function does not get called. Why?

meat5000: i can't change the second function from [server] to a [Command], because as per documentation [Command] is something you can use only within player objects, and my gamelord code (second function) exists within its own object that isn't owned by any client.

nisovin: the [server] tag in the second function apparently does not make any difference, as the problem remains the same with or without it, so i thought since that function actually has to run only on the server, might as well put the tag.

avatar image
0

Answer by sharat · Sep 24, 2015 at 02:51 PM

I don't think you can pass a GameObject as an argument to a Command function. You can only pass in simple arguments, NetworkIdentity's, and NetworkBehaviors to Command's/ClientRpc's. Also, I'm assuming this is a prefab you are passing in, so I don't think that NetworkBehavior's or NetworkIdentity's will work on it since they wouldn't have an instance id set by the server.

Instead, I would have some sort of helper function that can change the prefab reference to a index of some sort. Here's an example:

 [Client]
 public void CreateBuildingHere(Vector3 pos, GameObject prefabObject)
 {
     int prefabIndex = NetworkManager.singleton.spawnPrefabs.IndexOf(prefabObject);
     CmdCreateBuildingHere(pos, prefabIndex);
 }
 
 [Command]
 private void CmdCreateBuildingHere(Vector3 pos, int prefabIndex)
 {
     //some other non-related code
     GameObject prefabToSpawn = NetworkManager.singleton.spawnPrefabs[prefabIndex];
     gameLord.SpawnBuilding(playerId, pos, prefabToSpawn);
 }

Keep in mind, that this example may have problems if you are dynamically registering prefabs to your NetworkManager. You may want to have your own prefab indexing system instead of using the list of spawnPrefabs.

Comment
Add comment · 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
0

Answer by Lnoldori · Nov 27, 2015 at 10:24 AM

To @grandmapuckett I saw that you had already check the documentation but in order to have it as an answer here i give the following.

For anyone still having a similar problem although it has been answered already in a lot of other places.

From Unet Documentation : Remote Actions

Commands

Commands are sent from player objects on the client to player objects on the server. For security, Commands can only be sent from YOUR player object, so you cannot control the objects of other players.

The problem is that this will work for a client which is a host also, but not for a remote client. I think unity should warn about this and not let us think that is permitted.

To @sharat

Arguments to Remote Actions

  • GameObject with a NetworkIdentity component attached

Comment
Add comment · Show 1 · 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 otomo · Dec 29, 2015 at 11:34 AM 0
Share

I am a little bit late to the party but I am not sure if this

GameObject with a NetworkIdentity component attached

is also valid for prefabs or only for already instantiated gameobjects.

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

8 People are following this question.

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

Related Questions

NetworkServer method to spawn map objects (once in a match) 0 Answers

Spaw dynamic (unregistered) object on network (UNET) 0 Answers

UNet - Where does "normal" code run? 1 Answer

uNet Connection to IPv6 [Networking] 0 Answers

UNET NetworkServer.Spawn intermittently not called on clients 1 Answer


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