Search Unity

Question Can't destroy correctly object in MLAPI

Discussion in 'Multiplayer' started by ppaulikelis, Oct 22, 2021.

  1. ppaulikelis

    ppaulikelis

    Joined:
    Jun 15, 2021
    Posts:
    3
    Hello,

    I am trying to destroy specific object on mouse1 click. I am using Unity MLAPI 0.1.0. When I spawn object (SpawnPuzzlePieceServerRpc), I save it's network id into a NetworkVariable. Object then follows mouse cursor (MakeActivePuzzlePieceFollowMouseServerRpc). After that, if I press mouse 1 button, I want that spawned object to be destroyed. Method (DeleteActivePuzzlePieceServerRpc) destroys object both on host and client, however, method continues to be called for some reason, and throws KeyNotFoundException: The given key was not present in the dictionary. NetworkVariable (activePuzzlePieceNetId) seems to be updated to 0 (because of the error throwned constantly), so the method shouldn't be called again because of the condition in Update(). It feels like NetworkVariable is not syncing correctly here. What could be the problem and what am I doing wrong?

    Thanks in advance,

    Code (CSharp):
    1. public class PlayerTest : NetworkBehaviour
    2. {
    3.     [SerializeField] Transform[] puzzlePiecePrefabs;
    4.     NetworkVariable<ulong> activePuzzlePieceNetId = new NetworkVariable<ulong>(0);
    5.  
    6.     void Start()
    7.     {
    8.         activePuzzlePieceNetId.Settings.ReadPermission = NetworkVariablePermission.Everyone;
    9.         activePuzzlePieceNetId.Settings.WritePermission = NetworkVariablePermission.Everyone;
    10.     }
    11.  
    12.     void Update()
    13.     {
    14.         if (!IsLocalPlayer) return;
    15.  
    16.         if (!activePuzzlePieceNetId.Value.Equals(0))
    17.         {
    18.             if (Input.GetMouseButtonDown(1))
    19.             {
    20.                 DeleteActivePuzzlePieceServerRpc();
    21.             }
    22.             else
    23.             {
    24.                 MakeActivePuzzlePieceFollowMouseServerRpc();
    25.             }
    26.         }
    27.     }
    28.  
    29.     [ServerRpc]
    30.     void DeleteActivePuzzlePieceServerRpc()
    31.     {
    32.         NetworkObject puzzlePiece = NetworkSpawnManager.SpawnedObjects[activePuzzlePieceNetId.Value];
    33.         Destroy(puzzlePiece.gameObject);
    34.         activePuzzlePieceNetId.Value = 0;
    35.         DeleteActivePuzzlePieceClientRpc();
    36.     }
    37.  
    38.     [ClientRpc]
    39.     void DeleteActivePuzzlePieceClientRpc()
    40.     {
    41.        
    42.     }
    43.  
    44.     [ServerRpc]
    45.     public void SpawnPuzzlePieceServerRpc(int puzzlePieceId)
    46.     {
    47.         Transform puzzlePiece = Instantiate(puzzlePiecePrefabs[puzzlePieceId]);
    48.         puzzlePiece.GetComponent<NetworkObject>().SpawnWithOwnership(OwnerClientId);
    49.         activePuzzlePieceNetId.Value = puzzlePiece.GetComponent<NetworkObject>().NetworkObjectId;
    50.         SpawnPuzzlePieceClientRpc();
    51.     }
    52.  
    53.     [ClientRpc]
    54.     void SpawnPuzzlePieceClientRpc()
    55.     {
    56.     }
    57.  
    58.     [ServerRpc]
    59.     void MakeActivePuzzlePieceFollowMouseServerRpc()
    60.     {    
    61.         MakeActivePuzzlePieceFollowMouseClientRpc();
    62.     }
    63.  
    64.     [ClientRpc]
    65.     void MakeActivePuzzlePieceFollowMouseClientRpc()
    66.     {
    67.         NetworkObject puzzlePiece = NetworkSpawnManager.SpawnedObjects[activePuzzlePieceNetId.Value];
    68.         puzzlePiece.transform.position = GetMousePositionInWorld();
    69.     }
    70.  
    71.     Vector3 GetMousePositionInWorld()
    72.     {
    73.         var mousePos = Input.mousePosition;
    74.         mousePos.z = 19;
    75.         return Camera.main.ScreenToWorldPoint(mousePos);
    76.     }
    77. }
     
  2. luke-unity

    luke-unity

    Joined:
    Sep 30, 2020
    Posts:
    306
    Just chage `DeleteActivePuzzlePieceServerRpc` to:
    Code (CSharp):
    1.     [ServerRpc]
    2.     void DeleteActivePuzzlePieceServerRpc()
    3.     {
    4.         NetworkObject puzzlePiece = NetworkSpawnManager.SpawnedObjects[activePuzzlePieceNetId.Value];
    5.         Destroy(puzzlePiece.gameObject);
    6.     }
    7.  
    MLAPI will automatically despawn and destroy the objects on all clients. You are trying to send a ClientRpc on an already destroyed NetworkObject that's not supported.
     
  3. ppaulikelis

    ppaulikelis

    Joined:
    Jun 15, 2021
    Posts:
    3
    Sorry, but it did not work (or change anything). Still getting same errors. To me, it looks like on client (or server, not sure) activePuzzlePieceNetId (NetworkVariable) is not changed to 0, so DeleteActivePuzzlePieceServerRpc() is called (because in Update() activePuzzlePieceNetId != 0), but in DeleteActivePuzzlePieceServerRpc() it uses 0 value, where that object does not exist and throws error. No clue why this is happening.