Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Resolved Child class of NetworkBehaviour causes warning (Netcode)

Discussion in 'Multiplayer' started by JustCoolMan, May 12, 2023.

  1. JustCoolMan

    JustCoolMan

    Joined:
    Dec 8, 2015
    Posts:
    11
    I have VR multiplayer project. Theres a GrabObjectBase class which is a child of NetworkBehaviour.
    It has bool network variable isGrabbed:

    Code (CSharp):
    1. public NetworkVariable<bool> isGrabbed = new NetworkVariable<bool>(false, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server);

    I also have class GrabObjectWeapon which is a child of GrabObjectBase.
    All difference this class has is:

    Code (CSharp):
    1. public class GrabObjectWeapon : GrabObjectBase
    2. {
    3.     [Header("Grab Object Weapon")]
    4.     [SerializeField] Weapon m_weapon;
    5.  
    6.     void Start()
    7.     {
    8.         if (m_weapon == null)
    9.             m_weapon = GetComponent<Weapon>();
    10.     }
    11. }

    A have two prefabs one with GrabObjectBase and one with GrabObjectWeapon
    Both prefabs has NetworkObject component and both prefabs were added to network object list of NetworkManager.

    The problem is:
    When I NetworkObject.Spawn() the GrabObjectBase with isGrabbed == true - everything works well,
    When I NetworkObject.Spawn() the GrabObjectBase with isGrabbed == false - everything works well,
    When I NetworkObject.Spawn() the GrabObjectWeapon with isGrabbed == true - everything works well,
    When I NetworkObject.Spawn() the GrabObjectWeapon with isGrabbed == false - warning appears:
    NetworkVariable is written to, but doesn't know its NetworkBehaviour yet. Are you modifying a NetworkVariable before the NetworkObject is spawned?

    (I change isGrabbed state in the project window before spawn)

    What could be causing this error?
     
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    5,553
    We should see the code that modifies the NetworkVariable. From the sound of it I would say you change it before the object is being network-spawned. Check whether you set the value in Awake, Start or OnEnable. You have to wait for the OnNetworkSpawn event before changing the variable from what I remember.
     
  3. JustCoolMan

    JustCoolMan

    Joined:
    Dec 8, 2015
    Posts:
    11
    Theres code in two parts:
    (part 1 - spawn object)

    Code (CSharp):
    1. public class Player : NetworkBehaviour
    2. {
    3.     void CreateItemServerRpc(string itemName, HandType handType, ulong clientId) //create and spawn nework object
    4.     {
    5.         GameObject newObject = Instantiate(GameController.Singleton().GetEntity(itemName)); //spawning gameObject from "resources" folder
    6.  
    7.         NetworkObject networkObject = newObject.GetComponent<NetworkObject>();
    8.         networkObject.Spawn();
    9.  
    10.         ulong networkObjectId = networkObject.NetworkObjectId;
    11.  
    12.         CreateItemClientRpc(handType, clientId, networkObjectId);  
    13.     }
    14.  
    15.     [ClientRpc]
    16.     public void CreateItemClientRpc(HandType handType, ulong clientId, ulong objectId) //grab nework object
    17.     {
    18.         if (clientId != OwnerClientId)
    19.             return;
    20.  
    21.         HandInteractor handInteractor = GetHandInteractor(handType); // left or right hand in VR that can grab objects
    22.  
    23.         NetworkObject networkObject = GameController.Singleton().FindNetworkObjectById(objectId);
    24.         GrabObjectBase grabObject = networkObject.GetComponent<GrabObjectBase>();
    25.  
    26.         grabObject.Grab(handInteractor);
    27.     }
    28. }
    (part 2 - grab object and change networkVariable)

    Code (CSharp):
    1. public class GrabObjectBase : NetworkBehaviour
    2. {
    3.  
    4. public NetworkVariable<bool> isGrabbed = new NetworkVariable<bool>(false, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server);
    5.  
    6. public virtual void Grab(HandInteractor interactor)
    7.     {
    8.         if (grabPoints[0].handInteractor == null) //grabPoints is points where object can be grabbed
    9.         {
    10.             grabPoints[0].handInteractor = interactor;  //object is hold by hand interactor in grabPoint 0
    11.             grabPoints[0].handInteractor.grabbedObject = this; //hand interactor is holding object is in grabPoint 0
    12.             GrabServerRpc(interactor.player.OwnerClientId, interactor.handType, 0);
    13.         }
    14.     }
    15.  
    16.     [ServerRpc(RequireOwnership = false)]
    17.     public void GrabServerRpc(ulong playerId, HandType handType, int grabPoint)
    18.     {
    19.         Player player = GameController.Singleton().FindPlayerById(playerId);
    20.         HandInteractor handInteractor = player.GetHandInteractor(handType);
    21.  
    22.         if (OwnerClientId != player.OwnerClientId) // if grabObject owner is not owner of hand interactor
    23.         {
    24.             NetworkObject.ChangeOwnership(player.OwnerClientId);  // make grabObject same owner, the player holding it
    25.         }
    26.  
    27.         if (isGrabbed.Value == false) // <--- there changing the networkVariable, it's seems to be already spawned
    28.         {
    29.             isGrabbed.Value = true;
    30.         }  
    31.     }
    32. }

    The Spawn() function and the networkVariable change function (Grab()) are going together in one method, but it seems to be they are in the correct order.
    I tried to make delay before Grab() function, but it did nothing
     
    Last edited: May 14, 2023
  4. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    656
    I tried something similar and got strange behaviour if isGrabbed was public. Try making it protected or private.

    Edit: I just checked and it looks like 1.4.0 fixes the issue so give that a go.
     
    Last edited: May 14, 2023
  5. JustCoolMan

    JustCoolMan

    Joined:
    Dec 8, 2015
    Posts:
    11
    1.4.0 fixed the issue. Thank you