Search Unity

Instantiating with RPC problem

Discussion in 'Multiplayer' started by virror, Apr 16, 2012.

  1. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Yes, for networkID already in the scene. I cant sync with RPC before i have sync : p
    Well, its working, so im happy : )
     
  2. Bluntweapon

    Bluntweapon

    Joined:
    Feb 24, 2012
    Posts:
    158
    At the risk of sounding incredibly slow...why don't you leave the NetworkView to the ID the Scene gives you? I mean that's kinda the point of having a static NetworkView. As long as all the machines load up the same scene you're guarenteed to have the correct ID already attached. (This gets a little wonky when you switch scenes. You can have multiple of the same IDs present if any NetworkView had DontDestroyOnLoad called on it)

    Have whatever object the NetworkView is attached to in the first scene your application loads (even before you start a server or connect), call a DontDestroyOnLoad, and you're set.

    Unless I'm seriously missing something here, feeding an null to ViewID is not exactly stable.
     
    Last edited: May 18, 2012
  3. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Well, the whole point of this as i said before is that the server and client gets different IDs since they are in different scenes, That makes it impossible to sync anything cause i don't have a "start channel" to use.
     
  4. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Ok, this will probably sound a bit stupid, but anyway:
    The only way to set a networkViews owner is by "Network.AllocateViewID()" right? This will set the owner to that client.
    And every time "AllocateViewID" is used it creates a new ID that's unique for the whole network?
    If a networkView is already in the scene it will be owned by the server?
    How am i supposed to make sure all my networkViews have the same ID and still owned by their respective clients?
    If i use AllocateViewID and send that all clients will have the same owner, right?
    I know this is useful when synchronizing and stuff, but not always.

    I really feel like a noob here : p
     
  5. MariuszKowalczyk

    MariuszKowalczyk

    Joined:
    Nov 29, 2011
    Posts:
    301
    I would like to help you, but after trying to read the whole topic, I don't understand what are you trying to achieve and what is not working at the moment. I think I am doing something similar to you (I am not using Network.Instantiate()).

    Here is how I am doing things. I have a NetworkManager. This is just an empty object with a networkView attached to it and a NetworkManager script.

    Code (csharp):
    1.  
    2. static var instance : NetworkManager = null;
    3.  
    4. function Start()
    5. {
    6.     if (!instance)
    7.     {
    8.         instance = this;
    9.     }
    10. }
    You have to make the manager on both the client and the server (you will always have only one manager on the client and only one on the server). You don't have to do anything more with it (don't mess with the viewID). I am also using this NetworkManager to sync the data from the server to the clients (but still I don't need to mess with viewIDs here, since the server is the owner of the NetworkView by default).

    Now I can send RPCs from within any script I want:
    Code (csharp):
    1.  
    2. NetworkManager.instance.networkView.RPC("SyncScores", RPCMode.Others, scoreRed, scoreBlue, isAfterGoal, isAtCenter, isAfterGame, isOvertime, lastGoalRed);
    In my game, clients are sending RPCs only to the server (RPCMode.Server). I am never using RPCMode.All and RPCMode.Others on the client. The Network.isServer and Network.isClient functions can be helpful here.

    I also need to send the input from the client to the server. I am using another pair of NetworkViews for this (this time the client is the owner, so I have to mess with viewIDs and SetScope). Everything is working just fine.

    Like I said, I wish I could help you more. Maybe if you could explain your problem once again. What you are trying to achieve and what is working and what is not.
     
    Last edited: May 22, 2012
  6. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Hehe, this thread is a nice mix of different problems related to Instantiating, last questions were more of a general question only.

    What i am trying to achieve and how I'm doing that now:
    I want to Instantiate two different prefabs for every player that connects, so first i Instantiate the players prefab containing camera, a bunch of scripts, player arms and more, also creates a new ID with "Network.AllocateViewID" to be able to sync movements. Then i send an RPC to all other clients were i Instantiate "my" player in their game which is a different prefab, here I'm sending pos, rot, viewID and some other stuff from my own model. Then i send a RPC request to all other players telling them to run the Instantiate RPC on my client to get all their players spawned. This is were i run into some problems because i need to send my own NetworkPlayerID to the clients so they now who to respond to. Sending Network.player is obviously wrong as it crashes the server and editor and everything, so i tried to send networkView.owner instead. Problem here is that the only way for the client to be the owner is to use "Network.AllocateViewID", but then the server and other clients wont be owner if i have to send my ID to them. Another problem is that the server wont have the correct viewIDs when trying to sync, so currently i create a new networkView on the server for every new player, this is probably not a good solution, but it works : p

    Sorry for the ling post, but its obviously something I'm missing as this should be very basic networking stuff and easy to set up.

    Edit: Also, i run the server and client in different scenes which gave them different initial viewIDs, i made a small hack to get around this by setting "networkView.viewID = new NetworkViewID();" ugly, but it works, but again gives owner problems for me.
     
    Last edited: May 22, 2012
  7. MariuszKowalczyk

    MariuszKowalczyk

    Joined:
    Nov 29, 2011
    Posts:
    301
    I am not sure if I understand correctly. If you have 10 players connected to the server, you will have 10 (or 11) different NetworkViews on every client? That's why you need to send the viewID to other clients?

    You should probably send the position, rotation etc. only from the client to the server. Then the server could send it to other clients (even with your current logic Unity is doing this for you behind the scenes). Thanks to this, the client would not need to know the viewID of other clients and you will have only two NetworkViews on the client: the one that is sending your position to the server and the other that is receiving the data (other client's position) from the server. You will still need to have one NetworkView for every player on the server though.

    I would also recommend to send only the input from the client to the server not the position, because sending the position allows players to cheat. You should probably calculate the position on the server.

    In my game I am doing exactly this, and it's working like a charm. I don't know if I have helped you at all, but I was at least trying :D
     
  8. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Yes, every connected player prefab have their own networkID to make it super simple to sync movements using "OnSerializeNetworkView" and that part works pretty good except the part were i have to create networkVies on the server. What does not work is to send the clients NetworkPlayer to the other clients. If i try to send networkView.owner (the main networkView i use to sync stuff) then i wont send the correct NetworkPlayer info because its not owned by my client.

    If you are only using one view to get the movements for all players, then you need some identifier to tell what movement belongs to what player? In that case, wont that add unnecessary overhead?
     
    Last edited: May 22, 2012
  9. MariuszKowalczyk

    MariuszKowalczyk

    Joined:
    Nov 29, 2011
    Posts:
    301
    Why exactly do you need to send the NetworkPlayer to other clients?

    EDIT: If you really need this, maybe you can send this information form the server to the clients? It's in the Network.connections array on the server.
     
    Last edited: May 22, 2012
  10. George Foot

    George Foot

    Joined:
    Feb 22, 2012
    Posts:
    399
    Can't you just use Network.Instantiate on the client to create a stub object for comms, with the NetworkView attached? Then in a script on that object, from Start(), instantiate either the local player prefab or the remote player prefab, depending on whether the NetworkView is local or not. You also have the option of doing something totally different on the server, if that's useful - by instantiating a different prefab from Start().
     
  11. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Mariusz Kowalczyk: I just want to send an RPC to all clients, and want them to respond to me, cant be that rare?

    George Foot: That is a good idea, but how will the owners be set up then? I guess either the server or one client will be owner of all instances then? Is it impossible to have a networkView were each client is the owner of his part of the networkView?

    Just want to make this as simple as possible, i know i should have the server do a lot of stuff, but for this game i just want very simple networking : p
     
    Last edited: May 22, 2012
  12. George Foot

    George Foot

    Joined:
    Feb 22, 2012
    Posts:
    399
    The view is owned by whomever called Network.Instantiate to create it, regardless of whether that was local or not. So if each client, on joining, calls Network.Instantiate to create its player GameObject, you end up with one view per client, owned by that client, shadowed on all the other clients.
     
  13. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Ok, here is a more defined question: If i send my Network.Player with an RPC, then when the other client sends another RPC to this NetworkPlayer, the server crashes, even the whole Unity editor. This can be the expected behavior? : p
    Server does nothing, only has a dummy RPC defined, networkView with correct ID exist on both clients and server. Same RPC works if i send to RPCMode.Others or something similar. It specifies that "networkView.RPC" takes a NetworkPlayer as a parameter, is that not true? Do i need to use one of the "RPCMode" stuff? If so, that's just crazy : p