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

Unity Networking - Object synchronizing

Discussion in 'Multiplayer' started by rajmond, Jan 25, 2011.

  1. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
    Hello!

    I'm working in a project and I'm having very big trouble to make my project multiuser. What I need is to sync the position of objects (cubes) between clients. I checked the Unity networking example but that helps me just when I want to sync the First Person Controller but not other objects. Somebody knows some tips or which steps I should take?!


    Rajmond
     
  2. zehreken

    zehreken

    Joined:
    Jun 29, 2009
    Posts:
    112
  3. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
    Thanks

    I know this tutorial. I checked it many times, but I couldn't find what I needed.
    I have a scene with a Person Controller and many cubes, so when I drag one cube in a scene/client I want to synchronized the position of the cubes between all other clients.
    Today I managed is "somehow". I have a master server as a separate installation and then the clients. When a client connects to the server he instantiate the cube (and the person controller as well). So when there are many clients each of them can move just their cube which the instantiated!

    Any suggestions?!

    Rajmond
     
  4. zehreken

    zehreken

    Joined:
    Jun 29, 2009
    Posts:
    112
    Instiate cubes with Network.Instantiate and add a networkView component to the cube prefab, set State Synchronization to Reliable Delta Compressed. I'm also new to networking in Unity but as far as I understood this should work.
     
  5. PrimeDerektive

    PrimeDerektive

    Joined:
    Dec 13, 2009
    Posts:
    3,090
    Do you mean objects that are already in the scene (like decorations, crates, barrels and stuff) that you want all clients to be able to move around and have the results be synced across the network? Or player objects that are instantiated upon connection and controlled by their network owner?

    Can you show some code?
     
  6. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
    Exactly! I mean objects that are already in the scene ( decorations and that king of stuff)!
     
  7. PrimeDerektive

    PrimeDerektive

    Joined:
    Dec 13, 2009
    Posts:
    3,090
    That complicates things a little. If they are rigidbodies, I would grab the "NetworkRigidbody" script from the networking example in the resources section, add a networkview to all the objects that are in the scene by default, add the NetworkRigidbody script, and have the networkview observe it and see what happens.

    That might work, or you might have to do it authoritatively (have the server determine when players are interacting with physics objects, and broadcast the results to all players), because by default the server owns all objects with networkviews that are in a scene by default (that were not network.instantiated).
     
  8. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
    I did the first thing! Netwrokview observing the NetworkRigidbody attached to those objects, but didn't work!
     
  9. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
  10. PrimeDerektive

    PrimeDerektive

    Joined:
    Dec 13, 2009
    Posts:
    3,090
    Okay, what exactly are the players doing that is moving the object around that you want to sync? Shooting it? Picking it up/throwing it? Pushing it? And how does that work, script wise?
     
  11. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
    The objects have attached a "DragRigidbody" script which allows them to move it with the mouse, but I need to see movements by shooting them as well with different objects (bullets)! So I have a scene with all those cubes which you can move with mouse and then you can create other objects with key click and collide with objects on the scene.
     
  12. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
    So when I move the object in the server (with mouse drag, or colliding it) I see the movements in the clients, but when I move them in the client the movement is not shared! So somehow the serve owns objects?!
     
  13. PrimeDerektive

    PrimeDerektive

    Joined:
    Dec 13, 2009
    Posts:
    3,090
    Okay, that's probably your problem. DragRigidbody isn't really a network-enabled script by default, it just does everything locally. Even with a networkview and NetworkRigidbody, that's not going to help, because the server is the owner of those objects (because they were in the scene by default), so he is technically the only person that can move them and have the move be broadcasted over the network.

    you'll have to customize or write your own "networked" DragRigidbody to be authoritative, where the server is the only person running the code, determining when objects with the script collide with rigidbody objects, then apply force in the appropriate direction on the rigidbody with an RPC broadcasted to all the players.
     
  14. DJAZLAR

    DJAZLAR

    Joined:
    Feb 18, 2011
    Posts:
    37
    @legend411 do u have an example of how to implement this I am so struggling with the same type of issues too.
     
  15. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
    I found out how to make this work. Later today I will post my code which does it.
     
  16. DJAZLAR

    DJAZLAR

    Joined:
    Feb 18, 2011
    Posts:
    37
    thanks very much i appreciate it.
     
  17. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
    Code (csharp):
    1.     var position1 : Vector3;
    2.     var rotation1 : Quaternion;
    3.     var move : boolean;
    4.  
    5. function Update ()
    6. {
    7. move = false;
    8. position1 = gameObject.transform.position;
    9. rotation1 = gameObject.transform.rotation;
    10.  
    11.    
    12. }
    13.  
    14.  
    15. function OnMouseDrag () {
    16.  
    17.     networkView.RPC("SendMovement", RPCMode.OthersBuffered, position1, rotation1);
    18.     Debug.Log("On Mouse Drag: ");
    19. }
    20.  
    21. function OnMouseExit () {
    22.  
    23. Debug.Log("On Mouse Exit: ");
    24. }
    25.  
    26. @RPC
    27. function SendMovement(position1 : Vector3, rotation1 : Quaternion)
    28. {
    29.     gameObject.transform.position = position1;
    30.     gameObject.transform.rotation = rotation1;
    31. }
    32. [QUOTE][/QUOTE]

    Just attach this script to objects which you move with DragRigidbody and you should see their movements in all clients/server.
     
  18. DJAZLAR

    DJAZLAR

    Joined:
    Feb 18, 2011
    Posts:
    37
    thats awesome also is there a way to modify this code to check if an object has moved vector coords and if it does show all movements to all clients and server. I am having issues with ownerships in game and i didnt want to go full authoritative and if i could implement the code to check for a movement and if its changed then send information to other clients and server.
     
  19. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
    As seen from my code the function "OnMouseDrag" is called only when a user holds the mouse down and moves it. And the "DragRigidbody" script works exactly that way(holding mouse down on object's surface then move is with mouse). So whenever you move and object with mouse drag then the script send the RPC with the movements.
    I do not exactly understand your issue?
     
  20. DJAZLAR

    DJAZLAR

    Joined:
    Feb 18, 2011
    Posts:
    37
    this script is wonderful rajmond but my issue i was explainint if i have a game object in the scene is there a way to modify this to send movement information on a change in its vector position rotation without the mouse drag.

    so basically an object wouldnt send or update nothing until it physically moved from its position then update to other clients and server
     
  21. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
    I see the problem. I was struggling with this a lot actually. Because when you have a same object in two scenes and then you want to send the RPC when it has changed position that it will cause a problem because the same objects moves in two scenes and both users will have to send the RPC in both ways so it will cause a big lag and the object's will not move properly.
     
  22. DJAZLAR

    DJAZLAR

    Joined:
    Feb 18, 2011
    Posts:
    37
    lol yes i just tried this
    both screens see the movement but really strange glitching
     
  23. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
  24. DJAZLAR

    DJAZLAR

    Joined:
    Feb 18, 2011
    Posts:
    37
    if the server updates its position though it should be seen by everyone
     
  25. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
    Yes. All objects that are instantiated during runtime belong to the server and when he moves them everybody gets it.
    However if you have objects and you attach NetworkView's observing their transform's, they all will send the position (doesn't matter who created them), however they will send movement just on colliding (you hit the objects with something else), but the position that changed with mouse drag (DragRigidbody) won't be synced.
     
  26. DJAZLAR

    DJAZLAR

    Joined:
    Feb 18, 2011
    Posts:
    37
    yes i get the problem that no updates happen when client moves a server object as in a vehicle gets in and flies away its owned by server so noone sees the movement as its owned by the server unless u can think of a workaround to this like maybe if i do a check in the update I have botched this script together and just in process of tryin it but its probably wrong somewhere



    var doClientPosSmoothing : boolean = true;
    var doClientRotSmoothing : boolean = true;
    var clientPosSmoothing : float = 0.9;
    var clientRotSmoothing : float = 0.9;
    private var serverCurrentPos : Vector3;
    private var serverCurrentRot : Quaternion;
    private var serverLastPos : Vector3;
    private var serverLastRot : Quaternion;
    private var clientAuthoritativePos : Vector3;
    private var clientAuthoritativeRot : Quaternion;



    function OnNetworkInstantiate(info : NetworkMessageInfo)
    {

    if (doClientPosSmoothing) clientAuthoritativePos = transform.position;
    if (doClientRotSmoothing) clientAuthoritativeRot = transform.rotation;
    if (Network.isServer) {
    serverCurrentPos = transform.position;
    serverCurrentRot = transform.rotation;
    serverLastPos = serverCurrentPos;
    serverLastRot = serverCurrentRot;
    };
    }


    function Update ()
    {

    if (Network.isClient) {
    if (doClientPosSmoothing clientAuthoritativePos != null)
    transform.position = Vector3.Lerp(transform.position, clientAuthoritativePos, clientPosSmoothing);
    if (doClientRotSmoothing clientAuthoritativeRot != null)
    transform.rotation = Quaternion.Lerp(transform.rotation, clientAuthoritativeRot, clientRotSmoothing);
    };
    }


    function LateUpdate() {
    // If position or rotation have changed since last frame, notify the clients.
    if (Network.isServer) {
    serverCurrentPos = transform.position;
    serverCurrentRot = transform.rotation;
    if (serverCurrentPos != serverLastPos || serverCurrentRot != serverLastRot)
    {
    serverLastPos = serverCurrentPos;
    serverLastRot = serverCurrentRot;
    SetTransformData(serverCurrentPos, serverCurrentRot);
    networkView.RPC("SetTransformData", RPCMode.Others, serverCurrentPos, serverCurrentRot);
    };
    };
    }

    @RPC
    function SetTransformData(pos : Vector3, rot : Quaternion) {
    // Executed on the clients
    if (doClientPosSmoothing) {
    clientAuthoritativePos = pos;
    } else {
    transform.position = pos;
    };
    if (doClientRotSmoothing) {
    clientAuthoritativeRot = rot;
    } else {
    transform.rotation = rot;
    };
    }
     
  27. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
    It's difficult to understand the scenario like this. Could you send me your project (package) and I will check.
     
  28. DJAZLAR

    DJAZLAR

    Joined:
    Feb 18, 2011
    Posts:
    37
    its tricky send a package i got playmaker and other assetts installed too not just basic scripting at the moment .

    I can explain basically if a client presses f on the vehicle it then changes to a view inside the vehicle and controls the vehicle but the problem lies in ownership as the server owns the vehicle it has to move it. so how would I go about telling the server to move the vehicle i have tried in that script above but I am sure i missed somethin and your script worked when i tried that but got really strange movements when someone tried to use the vehicle but it updated to all clients and server in the game.
    Is there a way of doing this properly to be able to move a server object smoothly and without problems.

    All i want is for anyone to be able to enter the vehicle and update to all the movements it makes.

    If client moves vehicle noone sees it once he takes control there must surely be an easy answer to how to do this.
     
  29. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
    Try this: the function OnNetworkInstantiate is called just when the object is instantiated and no more, so put that code inside the Update() function and remove the OnNetworkInstantiate. Then you could try to send the RPC just to the server (RPCMode.Server).
     
  30. DJAZLAR

    DJAZLAR

    Joined:
    Feb 18, 2011
    Posts:
    37
    tried that had no luck but I edited the original script u sent and this is the closest i have got so far as server owns the vehicle so only the server needs to do its moving. as everyone else then sees the movement.


    Code (csharp):
    1. var position1 : Vector3;
    2. var rotation1 : Quaternion;
    3.    
    4. function Update ()
    5. {
    6.  
    7. position1 = gameObject.transform.position;
    8. rotation1 = gameObject.transform.rotation;
    9.  
    10. networkView.RPC("SendMovement", RPCMode.Server, position1, rotation1);
    11.     }
    12.  
    13. @RPC
    14. function SendMovement(position1 : Vector3, rotation1 : Quaternion)
    15. {
    16.  
    17. if (Network.isServer) {
    18.     gameObject.transform.position = position1;
    19.     gameObject.transform.rotation = rotation1;
    20. }
    this is functional and anyone can take control and everything updates but its not very smooth at all needs serious lag fixing to be added to it but at least it sort of works where everyone can see the movements but is there any way of smoothing out the position over all clients.
     
    Last edited: Mar 28, 2011
  31. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
    This is happening because you send the RPC without a condition, so all clients sent it to the server simultaneously at the same time!
     
  32. DJAZLAR

    DJAZLAR

    Joined:
    Feb 18, 2011
    Posts:
    37
    can u explain how i can go about fixing this what sort of conditions like its a vehicle that the script is on which is created by the server and I cant think how i can restrict this
     
  33. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
    It really depends from the scenario, and that's why I told you to send me your project. If those objects/cars are not in the scene then you could instantiate for every client their own (so all the players who call Network.Instantiate are the owners), and only they share the movement in the network when it changes!
     
  34. DJAZLAR

    DJAZLAR

    Joined:
    Feb 18, 2011
    Posts:
    37
    i am interested in that idea u are mentioning is that easy to achieve
     
  35. DJAZLAR

    DJAZLAR

    Joined:
    Feb 18, 2011
    Posts:
    37
  36. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
    I cannot access this link!
     
  37. DJAZLAR

    DJAZLAR

    Joined:
    Feb 18, 2011
    Posts:
    37
    cant u connect to it or
     
  38. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
    So for the clients you instantiate it like this:

    public var CarObj : Transform;

    function OnConnectedToServer() {
    Network.Instantiate(CarObj,transform.position, transform.rotation, 0);
    }


    and for the server to instantiate for itself you use:

    public var CarObj : Transform;

    function OnServerInitialized(){
    Network.Instantiate(CarObj,transform.position, transform.rotation, 0);
    }
     
  39. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
    I cannot open speedyshare. I do not know why (it says "Internal Error")
     
  40. DJAZLAR

    DJAZLAR

    Joined:
    Feb 18, 2011
    Posts:
    37
    would that do everything automatically from then on
     
  41. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
    that would instantiate for a server its own car/object, and for all possible clients who connect to the server as well. the function "OnConnectedToServer()" is called just by clients (as they connect to the server), so all client during the connection to the server, instantiate their own car/objects.
     
  42. DJAZLAR

    DJAZLAR

    Joined:
    Feb 18, 2011
    Posts:
    37
    will this method auto update positions and rotations using networkview observing the transform
     
  43. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
    I think so. With this solution all clients are owners of their cars, so it is like before when the server was the owner and he could move them all.
     
  44. DJAZLAR

    DJAZLAR

    Joined:
    Feb 18, 2011
    Posts:
    37
    where do i attach this script to player or car and i dont seem to see anything spawning for me
     
  45. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
    Attach it to player or create an empty game object ant attach it. However here "public var CarObj : Transform;" by default is empty. You need to fill the variable. In that game object where this script is attached you should browser for your objects (car) and attach it to this variable.
     
  46. DJAZLAR

    DJAZLAR

    Joined:
    Feb 18, 2011
    Posts:
    37
    yes i am doing this and nothing happens i look in heirachy and nothing spawned
     
  47. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
    are you creating the server and connecting clients to it?
     
  48. DJAZLAR

    DJAZLAR

    Joined:
    Feb 18, 2011
    Posts:
    37
    i am using lobby from m2h i host then get connected to then i start game
     
  49. rajmond

    rajmond

    Joined:
    May 18, 2010
    Posts:
    56
    are connecting clients to the server?
     
  50. DJAZLAR

    DJAZLAR

    Joined:
    Feb 18, 2011
    Posts:
    37
    i host i got a friend to join then i start game