Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Multiplayer Action

Discussion in 'Multiplayer' started by Xazerek, Sep 1, 2016.

  1. Xazerek

    Xazerek

    Joined:
    Nov 3, 2014
    Posts:
    134
    Hi, i want to destroy a barrel in multiplayer game. I made a script, but only server can destroy barrel. Clients are not able to do that. Some ideas what i do wrong?
    Code (csharp):
    1.  
    2. public class Barrel: NetworkBehaviour {
    3.  
    4.     [Client]
    5.     void OnMouseDown()
    6.     {
    7.             CmdTest();
    8.     }
    9.    
    10.     [Command]
    11.     void CmdTest()
    12.     {
    13.         Destroy(gameObject);
    14.         RpcDestroy();
    15.     }
    16.    
    17.     [ClientRpc]
    18.     void RpcDestroy()
    19.     {
    20.         Destroy(gameObject);
    21.     }
    22. }
    23.  
     
  2. Chom1czek

    Chom1czek

    Joined:
    Sep 19, 2015
    Posts:
    66
    Code (CSharp):
    1. [Command]
    2. void CmdTest()
    3. {
    4.    NetworkServer.Destroy(gameObject);
    5. }
    This should do the trick. It will be destroyed on server and then applied to all connected players
     
  3. Xazerek

    Xazerek

    Joined:
    Nov 3, 2014
    Posts:
    134
    Your, and my script example is working well, but only if host press the barrel. If client click on the barrel nothing happens, even on client.
     
  4. Chom1czek

    Chom1czek

    Joined:
    Sep 19, 2015
    Posts:
    66
    Because if it's an non-player object then you have to re-assign the authority before sending a command.

    But before reassigning authority check this one, I want to see if it works.

    Code (CSharp):
    1. [Command]
    2. public void CmdTest(GameObject gameObject)
    3. {
    4.    NetworkServer.Destroy(gameObject);  
    5. }
    if not then:
    Code (CSharp):
    1. [Command]
    2. public void CmdAssignAuthority(GameObject barrelObject, NetworkConnection myConnection)
    3. {
    4.    barrelObject.GetComponent<NetworkIdentity>().AssignClientAuthority(myConnection);
    5. }
    and then call destroy.

    NetworkConnection you can find on any NetworkBehaviour script and it's called: connectionToClient
     
  5. Xazerek

    Xazerek

    Joined:
    Nov 3, 2014
    Posts:
    134
    Code (csharp):
    1. CmdAssignAuthority(barrel, connectionToClient);
    or
    Code (csharp):
    1. CmdAssignAuthority(barrel, NetworkBehaviour.connectionToClient);
    are not working. I don't understand how can i make it work
     
  6. Xazerek

    Xazerek

    Joined:
    Nov 3, 2014
    Posts:
    134
    This is my script for now:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using UnityEngine.Networking;
    4. using System.Collections;
    5.  
    6. public class BarrelDestroying: NetworkBehaviour {
    7.  
    8.  
    9.         public NetworkConnection connectionToClient;
    10.         public GameObject barrel;
    11.  
    12.  
    13.     [Client]
    14.     void OnMouseDown()
    15.     {
    16.             CmdAssignAuthority(barrel, connectionToClient);
    17.     }
    18.    
    19.     [Command]
    20.     public void CmdAssignAuthority(GameObject barrelObject, NetworkConnection myConnection)
    21.     {
    22.       barrelObject.GetComponent<NetworkIdentity>().AssignClientAuthority(myConnection);
    23.       Debug.Log("Acces Granted");
    24.     }
    25. }
    26.  
    Im getting an error:
    Code (csharp):
    1.  
    2. UNetWeaver error: Command [BarrelDestroying:CmdAssignAuthority] cannot use a NetworkConnection as a parameter. To access a player object's connection on the server use connectionToClient
    3.  
    I don't understand what am i doing wrong.
     
  7. Chom1czek

    Chom1czek

    Joined:
    Sep 19, 2015
    Posts:
    66
    Sorry I misguided you, I noticed myself that you cannot pass NetworkConnection to [Command] method.
    Well if you want it to do something when clicked maybe this approach:
    Code (CSharp):
    1. void Update()
    2. {
    3.    if( ! isLocalPlayer) return;
    4.  
    5.    if(Input.GetKeyDown(Mouse.0)
    6.    {
    7.      Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    8.      RaycastHit hit;
    9.      if(Physics.Raycast(ray, out hit, 100f)
    10.      {
    11.         CmdDoSomethingWithBarrel(hit.collider.gameObject);
    12.      }
    13. }
    Code (CSharp):
    1. [Command]
    2. public void CmdDoSomethingWithBarrel(GameObject barrel)
    3. {
    4.    barrel.GetComponent<BarrelComponent>().DoSomething();
    5.    NetworkServer.Destroy();
    6. }
    if not then this last chance:
    Code (CSharp):
    1. [Command]
    2. private void CmdReassignAuthority(GameObject barrel)
    3. {
    4.    barrel.GetComponent<NetworkIdentity>().AssignClientAuthority(connectionToClient);
    5.    NetworkServer.Destroy();
    6. }
    7.  
    8.  
    About that NetworkConnection you missunderstood me or I described it poorly, anyway you can access it in every NetworkBehaviour component just by typing: connectionToClient, you don't have to cache it or anything :)
     
  8. Xazerek

    Xazerek

    Joined:
    Nov 3, 2014
    Posts:
    134
    Ehh..
    When im using the second solution client on start receive an error:
    Code (csharp):
    1.  
    2. InvalidOperationException: out of sync
    3.  
    When client click on barrel:
    Code (csharp):
    1.  
    2. Trying to send command for object without authority.
    3.  
    Both not working.
    Maybe someone from unity team has solution for this?
    If there is no solution for that, then how to make multiplayer interactions with door, etc?