Search Unity

networkView.owner issue

Discussion in 'Multiplayer' started by rogue_9, Jun 11, 2010.

  1. rogue_9

    rogue_9

    Joined:
    Jun 2, 2010
    Posts:
    4
    So when I use this on the server end it works correctly. However, when I use networkView.owner on any of the clients it always returns 0. I was wondering if there is something I have to do because it is being used on the client.

    Here's an example of what I am doing:

    Code (csharp):
    1. if (!networkView.isMine)
    2. {
    3.     Debug.Log(networkView.owner.ToString());
    4. }
    5.  
    fairly straight forward, but it always says 0.

    Any help is greatly appreciated.
     
  2. rogue_9

    rogue_9

    Joined:
    Jun 2, 2010
    Posts:
    4
    is this a known issue? if so can someone direct me to something that talks about it?
     
  3. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    0 is correct
    owner 0 = server (network player with player 0)


    the one that creates the view / allocates the view id is the owner.
    So if you use network.instantiate on the server, the server owns it
     
  4. rogue_9

    rogue_9

    Joined:
    Jun 2, 2010
    Posts:
    4
    wouldn't networkView.owner.ToString() return 0 on the server too then? it is giving me 1, 2, 3, etc when I use it on the server.

    Also I am talking about the ...owner.ToString() output specifically.
     
  5. duhprey

    duhprey

    Joined:
    Nov 13, 2009
    Posts:
    166
    I'm not sure if you'd call it a bug, but what's happening is that even though one of the clients created that networkview, it's also reflected on the server for every other client. That means that to any client all network views it didn't create are "Server". But on the server it sees everyone's creation as their own.

    You'll need to use another mechanism like an RPC sent from each player sending its Network.player which won't get changed by the server.
     
  6. cerebrate

    cerebrate

    Joined:
    Jan 8, 2010
    Posts:
    261
    Yeah, this is kind of a bug. I found this out the hard way.


    Only the server and the owners themselves know who the 'networkView.owner' is. Clients will always think that either they own an object, or the server owns the object, never actually another client.

    Basically, to get around this, if I did an rpc from one client to another using the networkView.owner, I would have in the script a check on the server that would see if the server actually owned the object, and if it didn't, it would forward the message on to the correct owner.
     
  7. MikeHergaarden

    MikeHergaarden

    Joined:
    Mar 9, 2008
    Posts:
    1,027
    Note that clients only know about the server. There are only connections between the server and client(s). When a client sends an RPC to a specific other client, it is routed via the server.
     
  8. PrimeDerektive

    PrimeDerektive

    Joined:
    Dec 13, 2009
    Posts:
    3,090
    When you use RPCMode.All, it reroutes it behind the scenes, though, right?

    For example, a client calls an RPC with RPCMode.All, that call will automatically be sent to the server and then sent to all clients, right? I was under the impression that you shouldn't have to do RPCMode.Server and then have the server do the RPCMode.All? Because I swear I've successfully used RPCMode.All from a client and it hit other clients.
     
  9. MikeHergaarden

    MikeHergaarden

    Joined:
    Mar 9, 2008
    Posts:
    1,027
    Yes it all works.
    The routing is completely hidden when using .Others .All or even sending to any of the NetworkPlayers.
    The only time you notice this hidden behaviour is when checking Network.connections: Clients always only have the servers connection and only the server can have more than 1 connection there.
     
  10. PrimeDerektive

    PrimeDerektive

    Joined:
    Dec 13, 2009
    Posts:
    3,090
    That's what I thought, thanks.

    So a client can technically call an RPC directly on another client if he knew what Network.Player that client was, the only caveat is that he cannot discover what Network.Player that client is by checking the owner of the object, because that will appear to be the server.

    Also, slightly unrelated, but given the new feature in 3.2:

    Am I correct in assuming that calling:

    Code (csharp):
    1. function OnPlayerDisconnected(player : NetworkPlayer) {
    2.     Network.RemoveRPCs(player);
    3. }
    Will actually remove Network.Instantiate calls from the buffer (although according to a post from Larus on the forums, it was supposed to before anyway)?

    Lastly, with all the new NAT bug fixes, does that require any changes to the sample projects in your ultimate networking package?
     
  11. MikeHergaarden

    MikeHergaarden

    Joined:
    Mar 9, 2008
    Posts:
    1,027
    Yes you can call RPCs using the NetworkPlayer info directly (instead of RPCMode).

    "Am I correct in assuming that calling:"
    No: In your example you use the NetworkPlayer, but the new feature is about using the instantiated gameobjects first NetworkView viewID:
    Network.RemoveRPCs (viewID : NetworkViewID)
    Like the doc states: You only need to call this on the first networkView from the gameobject.
    For this to work I guess you need to manually track which object belong(ed) to which player.

    No, my networking classes/functions dont require any changes :).
     
  12. Kryptos

    Kryptos

    Joined:
    Mar 30, 2011
    Posts:
    29
    I'm running through the same problem, but with the OnNetworkInstantiate method.
    On any client, info.sender is always the server. Because of that it is really difficult to track instance ownership.

    I think it is a bug, since even the documentation give as an example a script that doesn't work the way it is supposed to.
    http://unity3d.com/support/documentation/ScriptReference/Network.OnNetworkInstantiate.html

    How can I get the owner of an object without sending a RPC every time somebody instantiates an object?
     
  13. MikeHergaarden

    MikeHergaarden

    Joined:
    Mar 9, 2008
    Posts:
    1,027
    The one who wrote the doc also missed that indeed.
    info.sender is always the sender on the clients since it forwards messages from other clients. It would've been better if it ignored this fact and just put there who actually send the message.

    Doesn't checking networkview.owner help? Otherwise add the Network.Player to a RPC call.
     
  14. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    Yeah agree with leepo, thats what NetworkView.owner is for.

    I thought also agree that the info.sender is a bit useless like that, but instead of "fixing it" I would like to see it cut so if you need to know the explicit sender you would send it through yourself and otherwise its just not there (saves bandwidth)