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 CapSovaa · Mar 13, 2018 at 05:28 PM · instantiatemultiplayernetworkclient

server command works from host, but not from remote client

Hello, I have been trying to figure this out for days now, no luck, maybe someone can help me out.

Basically I am trying to instantiate an ammo prefab, using an empty object already in scene as transform reference.

 [Command]
     void CmdPlayerShootingControl()
     {
         Debug.Log("CMD Firing.");
 
         GameObject ammoShoot = Instantiate(ammoPrefab, tempFireTS.position, tempFireTS.rotation);
         NetworkServer.Spawn(ammoShoot);
     }

This is the cmd code Im calling on GetKeyDown. As you can see I am instantiating ammoPrefab, at tempFireTS. position/rotation.

Heres the problem, it works fine on host client, but nothing happens on remote client. The confusing part is, if I use transform.position/rotation to reference the script object itself it will work, but in that case my shoots arent getting fired were they need to be fired.

In short, cmd works if using transform.poistion/rotation, but not if using any other transform.

Here is the whole code.

 public GameObject ammoPrefab;
 public List<Transform> firePoints;
 private Transform tempFireTS;
 private int fireIndex = 0;
 
 void Update ()
     {
         if (!hasAuthority)
             return;
 
 
         
         if (Input.GetKeyDown(KeyCode.Mouse0))
         {
             Debug.Log("ButtonPressed.");
             tempFireTS = firePoints[fireIndex];
             InstantiateAmmo();
         }
 
 
     }
 
     void InstantiateAmmo()
     {
         Debug.Log(" 'InstantiateAmmo' called, calling CMD.");
         CmdPlayerShootingControl();
         fireIndex++;
         if (fireIndex <= firePoints.Count - 1)
         {
             tempFireTS = firePoints[fireIndex];
             Invoke("InstantiateAmmo", Random.Range(0.02f, 0.2f));
             Debug.Log("'InstantiateAmmo' if end.");
         }
         else
         {
             Debug.Log("'InstantiateAmmo' else end.");
             fireIndex = 0;
         }
 
     }
 
 [Command]
     void CmdPlayerShootingControl()
     {
         Debug.Log("CMD Firing.");
 
         GameObject ammoShoot = Instantiate(ammoPrefab, tempFireTS.position, tempFireTS.rotation);
         NetworkServer.Spawn(ammoShoot);
     }


And, all the NetworkIdentity, local Authority ..etc are set up, Ive checked a thousand times.

P.S. This is my first time asking on unity forums, srry if Im asking in wrong place.

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

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by Bunny83 · Mar 14, 2018 at 04:10 PM

You have several issues here. First of all you haven't mentioned to which object this script is attached to. It has to be attached to the playerobject of each player. Only the playerobjects can actually send commands to the server.


The next issue is that you set your client - local variable "tempFireTS" to some transform but the command method is executed on the server so it will use the "tempFireTS" variable on the server.


Since this seems to be some sort of "burst fire" since you will iterate through all "firePoints" when you click once it would make much more sense to only send the command once and let the server do the burst fire. This has several advantages. First of all you don't need to send a seperate command across the network for each bullet fired. Second you prevent a cheating user from simply reducing the burst fire rate.


I assume that the "firePoints" list are some sort of child objects of the player to act as spawn points for each shot? In this case each player object should have it's own spawn point list. So when executing the code on the server, the server has access to the same spawn point list.


You may want to do something like this:

 public GameObject ammoPrefab;
 public List<Transform> firePoints;
 private bool readyToFire = true;
 
 void Update ()
 {
     if (!hasAuthority)
         return;
     if (Input.GetKeyDown(KeyCode.Mouse0))
     {
         CmdPlayerShootingControl();
     }
 }
 
 [Server] 
 IEnumerator BurstFire()
 {
     readyToFire = false;
     foreach (var spawnPoint in firePoints)
     {
         GameObject ammoShoot = Instantiate(ammoPrefab, spawnPoint.position, spawnPoint.rotation);
         NetworkServer.Spawn(ammoShoot);
         yield return new WaitForSeconds(Random.Range(0.02f, 0.2f));
     }
     readyToFire = true;
 }
  
 [Command]
 void CmdPlayerShootingControl()
 {
     if (readyToFire)
     {
         StartCoroutine(BurstFire())
     }
 }

This will just send the command of the action the user want to perform to the server. The server will start a coroutine (unless one is already running) which does the actual spawning of the objects.


That way the server has full control over the actual burst fire action.

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 CapSovaa · Mar 14, 2018 at 08:23 PM

Thank you very much, this does indeed make the command do something, but Im not quite there yet.

Due to the nature of the project, I have a player object (the one in network manager) wich spawns a player character for the player to control. That is because of the multiple character choices for the player.

In my case player charater is a ship with cannons. On player character object I use camera ray to chose wether to shoot left or right set of cannons depending on which way the player is looking, and I store appropriate cannon transforms (firePoints) in a list.

You said only player objects can call commands, so I modified my scripts so the playerObject script makes a reference to playerCharacter script.

 public GameObject characterPrefab;
 public PlayerCharaterScript playerChar;
 
 [Command]
 CmdSpawnPlayerCharater()
 {
        GameObject tempCharacter = instantiate(characterPrefab);
         NetworkServer.SpawnWithClientAuthority(tempCharacter, connectionToClient);
 
         playerChar = tempCharacter.GetComponent<PlayerCharacterScript>();
 }

and now within that same playerObject script I am trying to get the freshest list of transforms just before calling the command, like this.

  private List<Transform> firePoints;
     
     void Update()
     { 
            if(Input mouse)
             {
                  firePoints = playerChar.firePoints;
                  CmdPlayerShootControl();
              }
     }

Now the problem which shows itself is this: Again, on host it works, on client(which I run in editor) it gives me "null reference, objetc not set...etc" error. Basically, on the host firePoints in playerObject script get updated from playerCharacter script, on the client nothing.

My guess....actually, the fact is, I believe, I'm not updating the server about this change of transforms in the list.

So to summarise, different characters will have different number of cannons, so I cant put a fixed list on playerObject prefab, but I can spawn a character from prefabs, and and check for cannon transforms on those character objects during runtime, but I'm stuck at how to update the server about that new list.

I apologize for making a big deal out of something probably basic, Im just geting into networked scripting, and just like in games, playing singleplayer dosent quite prepare you for multiplayer :D Still tryin to make sense in my head about client/server connections.

Thanks in advance.

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 Bunny83 · Mar 14, 2018 at 10:15 PM 0
Share

Well, if you spawn your ship with client authority the player will own that object and is the only one who can send commands to that objectwhich are executed on the server.

However this piece of code doesn't make sense again:

  void Update()
  { 
         if(Input mouse)
          {
               firePoints = playerChar.firePoints;
               CmdPlayerShootControl();
           }
  }

Even though you seem to call the "CmdPlayerShootControl" method locally, actually you don't. Commands are actually RPC calls that are send to the server and that method is actually executed on the server. Setting local variables on the client is pointless as the server doesn't see those changes.


Almost all your game logic should be executed on the server anyways. If you look at the code in my answer, only the update method will be called on the client. Everything else will be executed on the server.


If the ship is owned by the client you can simply send the command directly to that ship. However the selection of spawn points should be done on the server.


Alternatively you can send "parameters" to command method but you have to be careful. Sending a Transform reference does only work if that transform is actually a "networked object" itself. So it has to have a NetworkIdentity and has to be spawned properly. You can't magically transfer a reference to an arbitrary object which doesn't have a NetworkIdentity onto another PC. Each client does have the same objects but Unity doesn't have a clue the transform on client A is the same as on Client B.


After all it should be the server who decides which cannon of your ship is able to fire and not the client. The first rule in and server - client model is: Never trust the client. The server is THE authority when it comes to game state decisions. A client just tells the server what he want to do and the server does it.

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

144 People are following this question.

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

Related Questions

How can I spawn a GameObject on all players in my multiplayer game? 0 Answers

PhotonNetwork.Instantiate 2 problems. 3 Answers

Client interact with World Objects 0 Answers

Passing random values to a client. 0 Answers

Network.Instantiate is CHAOS. 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