Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only.

    Please, do not make any changes to your username or email addresses at id.unity.com during this transition time.

    It's still possible to reply to existing private message conversations during the migration, but any new replies you post will be missing after the main migration is complete. We'll do our best to migrate these messages in a follow-up step.

    On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live.


    Read our full announcement for more information and let us know if you have any questions.

Question How to get a reference of a spawned by host object for a client

Discussion in 'Multiplayer' started by Zabei, Apr 25, 2023.

  1. Zabei

    Zabei

    Joined:
    Jul 20, 2021
    Posts:
    4
    I'm really new to netcode and relay stuff but i'm just hardstuck on understanding what is the best/easiest way to get a reference of an object that has been spawned by other player. I have a script that gets the NetworkObjectId of my spawnedCube but of course, that works only on the host which spawns the cube and so has the reference to it. I also can't seem to understand the concept of RPCs because i've taken the RPC part from somewhere and it does change the color for all players but earlier when i tried something similar, i just had the ClientRpc in script on my object that was changing the color for everyone just fine aswell. So why calling the ClientRpc on the object itself changes it for everyone but if i call the RPC from the player i need to use this more complicated system of calling the ClientRpc through ServerRpc?(All i could understand is that calling it that way means we call ClientRpc on all clients but i'm not sure if i got that correctly and even if i did, still, what is the difference from calling only the ClientRpc on the object itself?)

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Unity.Netcode;
    5.  
    6. public class PlayerNetwork : NetworkBehaviour
    7. {
    8.     [SerializeField]private GameObject cubePrefab, spawnedCube;
    9.     void Update()
    10.     {
    11.         if(!IsOwner) return;
    12.      
    13.         if(Input.GetKeyDown(KeyCode.T)){
    14.             if(IsServer){
    15.                 spawnedCube = Instantiate(cubePrefab);
    16.                 spawnedCube.GetComponent<NetworkObject>().Spawn();
    17.             }
    18.         }
    19.         if(Input.GetKeyDown(KeyCode.C)){
    20.             redClientRpc(spawnedCube.GetComponent<NetworkObject>().NetworkObjectId);
    21.         }
    22.  
    23.         Vector3 moveDir = new Vector3(0,0,0);
    24.  
    25.         if(Input.GetKey(KeyCode.W)) moveDir.z += 1f;
    26.         if(Input.GetKey(KeyCode.S)) moveDir.z += -1f;
    27.         if(Input.GetKey(KeyCode.A)) moveDir.x += -1f;
    28.         if(Input.GetKey(KeyCode.D)) moveDir.x += 1f;
    29.  
    30.         float moveSpeed = 3f;
    31.         transform.position += moveDir * moveSpeed * Time.deltaTime;
    32.     }
    33.  
    34.     [ServerRpc]
    35.     private void startRedServerRpc(ulong networkObjectId){
    36.         redClientRpc(networkObjectId);
    37.     }
    38.  
    39.     [ClientRpc]
    40.     private void redClientRpc(ulong networkObjectId){
    41.         if(NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(networkObjectId, out NetworkObject networkObject)){
    42.             GameObject cube = networkObject.gameObject;
    43.             cube.GetComponent<MeshRenderer>().material.color = Color.red;
    44.         }
    45.     }
    46. }
     
  2. maxkcy

    maxkcy

    Joined:
    Oct 11, 2021
    Posts:
    64
    There are 2 ways in general to reference a network object. The right way is to use NetworkObjectTargetReference,
    Code (CSharp):
    1.  
    2. [ClientRpc]
    3.     private void GetSomeNetworkObjectAndDoSomethingClientRpc(NetworkObjectReference target)
    4.     {
    5.         if (target.TryGet(out NetworkObject networkObject))
    6.         {
    7.               // do stuff
    8.         }
    9.     }
    10.  
    and there is another way, (the bad way because I was using it by mistake)

    Code (CSharp):
    1.  
    2. [ServerRpc]
    3.     public void FindSomeNetworkObjectOnServerServerRpc(ulong networkObjectId, ServerRpcParams serverRpcParams = default)
    4.     {
    5.         if (NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(networkObjectId, out NetworkObject netObj))
    6.         {
    7.          
    8.                 // Do something
    9.             }
    10.    }
     
    malkere likes this.