Changing object ownership while object might be moving

Suppose you had a NetworkTransform owner by the server. You give ownership to a player and they pick up the item with their mouse and start moving it around. All of this is automatically handled by Unity’s NGO system. But while the player is moving the item, the server decides to take back ownership. However because of latency, one or two more NGO created server rpcs hit the server to continue moving the item, causing unity errors about a client tried to change network variables that they don’t own.

I know this is my issue because if the player stops moving the item and then the ownership changes, there are never any issues.

What is the natural way to handle this?

You should instead post any console messages you get, your code and what the behaviour is rather than indulging in guesswork. :wink:

If you send these RPCs manually then on the server side the code checks if the client is still the owner or not, and if he is not, the RPC is simply ignored.

Thanks, but no guess work at all. Easy to reproduce and prove.

I’d just like to know how this would be handled even theoretically. If a player owns a network transform and is freely moving it around (handled in Update or FixedUpdate) when the server takes back ownership, some NGO (ie code I did not write) RPCs are still processed on the server after the ownership was revoked. This results in errors about the client trying to write to network variables they don’t own (the item in question’s position data).

Here is the error on the server side

[Netcode] Client wrote to NetworkVariable`1 without permission. No more variables can be read. This is critical. => NetworkObjectId: 39 - GetNetworkBehaviourOrderIndex(): 1 - VariableIndex: 1

On the client, the code to pick up, move, and drop items

public void Update() {
    if (Input.GetMouseButtonDown(0))
    {      
      // Sends an RPC to the server asking if the client can pick up the item.
      // If valid, the server sets the player's "selectedItem" NetworkBehaviourReference
      this.OnClickItem(this.highlightedItem);
    }
    else if (Input.GetMouseButtonUp(0))
    {
      if (this.selectedItem)
      {
       // Sends an RPC to the server to drop the item, not really relevant here
        this.OnReleaseItem();
      }
    }
    else if (this.selectedItem)
    {
      // Simply sets the transform.position to the player's mouse position.
      // Since this is happening in an Update() it is sent often, and this means
      // that if the server suddenly takes back control over the item, one or more
      // NGO RPCs modifying the item's transform are processed on the server.
      // I've tried to use more RPCs to tell the client "hey, you can't drag anymore"
      // but it just doesn't work reliably. 
      this.DragItem(this.selectedItem.GetTransform());
    }
}

To reiterate, I’m trying to solve ownership issues where a client is actively modifying the position of a network transform it owns, and the server takes back ownership, but due to latency and timing, some previous RPCs to move the item are still processed by the server after-the-fact.

OK well I decided to upgrade to Unity 6 and, lo and behold, it is fixed.

1 Like

I know it’s solved but this message made me remember that there is a flag in NetworkManager’s Inspector and I always wondered what the use case for this was. Perhaps yours is the one! :wink:

image

Be sure to read the tooltip as it seems to indicate that clients who write but are not permitted would still allow the variable to be readable by everyone. I suppose this changes the “critical” error to one that’s just ignored at the expense of a few CPU cycles.

1 Like

Hmm… to me it reads about “length” as in message size and boundaries, like if the client is supposed to send an int16 but sends an int32 instead. Mine is/was always unchecked.