Search Unity

[RELEASED] Smooth Sync - Smoothly network rigidbodies and transforms while reducing bandwidth

Discussion in 'Assets and Asset Store' started by Fuestrine, Aug 4, 2017.

  1. Irye

    Irye

    Joined:
    Feb 17, 2017
    Posts:
    4
    Last edited: Oct 18, 2017
  2. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    590
    @logixworx
    I'm not really sure what you are asking. What's the physics and networking systems you are using and what do you want to switch to?
     
  3. SpindizzyGames

    SpindizzyGames

    Joined:
    Jun 29, 2017
    Posts:
    108
    Fuestrine: I am using netcode.io and bullet physics instead of Unity's llapi/hlapi and PhysX
     
  4. SpindizzyGames

    SpindizzyGames

    Joined:
    Jun 29, 2017
    Posts:
    108
  5. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    590
    @Irye
    Sorry about the late reply. Completely missed your message the last time I was here. I'll check out if pooling causes problems and get back to you.

    @logixworx
    I have no clue if you can use that stuff with Smooth Sync. We sync rigidbodies for the physics and UNET is what syncs them. Let me know if I'm not understanding correctly or if you have questions.
     
  6. Eruheran4

    Eruheran4

    Joined:
    Jan 6, 2013
    Posts:
    19
    Does it and if so, how does it work if I'm not using the NetworkTransform-Script of Unity? I have got my proper server and client. Thanks!
     
  7. SpindizzyGames

    SpindizzyGames

    Joined:
    Jun 29, 2017
    Posts:
    108
    Eru: I just asked that question right before you did. I think he said we're pretty much on our own heh. I looked over the code for SmoothSync - the code seems simple and straightforward enough to isolate Unity's network & controller parts and plug in the equivalent functions from the lib of your choice. My client is C# and server is in C++ - when I isolate the Unity stuff out so that it's all standard C# API code, I'm gonna run it through a C# to C++ converter then plug that into the C++ version of my libraries. Hopefully it works - it'll be a time saver.
     
  8. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    590
    @Eruheran4 If you are using UNET, you should be able to drag and drop it onto any object to have it sync. Let me know if I'm not understanding your question correctly.

    @logixworx Yeah, as far as converting C# to C++, good luck, lol. I'll try to help if you have any specific questions though.

    @Irye @TheBored
    You all may have the same problem, not entirely sure. So I spawned via the pooling method described here and everything works. I did run into one problem though, and that's that I wasn't assigning authority to the spawned objects when they had localPlayerAuthority checked on the NetworkIdentity. If you uncheck localPlayerAuthority, the server will be the owner automatically. If you want the client to be the owner you will have to set the authority with GetComponent<NetworkIdentity>().AssignClientAuthority(conn);

    Let me know if this doesn't fix your problem but I'm pretty sure you all just aren't setting authority, and without authority, it doesn't know who should be receiving and who should be sending updates.

    If this isn't your problem, sending me the problem in the example scene or a stripped down version of your game, or replication steps will help me see what's going wrong.
     
    Last edited: Oct 28, 2017
  9. andrew210

    andrew210

    Joined:
    Apr 23, 2014
    Posts:
    241
    Looks like an excellent tool, have bought it just to learn from it more than anything else at the moment, is there any chance in future that it may be extended for more general use so we can use it with any network package (I use SmartFox server and it would be great if I could use it with that :) )
     
  10. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    590
    @andrew210
    I'm not sure it can be generalized and still work. I'd make a specific version if there was enough demand for a certain way, but people seem pretty scattered in what they are using.

    I might add a little quick guide for people to convert themselves though, pointing out a few places where people would replace the UNET with whatever non UNET system they are trying to use. Probably around the next time I update the asset store build.
     
    SpindizzyGames likes this.
  11. andrew210

    andrew210

    Joined:
    Apr 23, 2014
    Posts:
    241
    Thanks! It was good learning experience for me converting it myself, it works pretty well really! The only issue really is that I'm not that sure that I've created a suitable replacement for GetNetworkTimestamp (I have an alternative timestamp thats in sync across all clients and is just a plain unix timestamp)
     
  12. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    590
    @andrew210
    Any timestamp should work there. Let me know if it's acting funky compared to the non-converted version though and I'll look into it more.
     
  13. SpindizzyGames

    SpindizzyGames

    Joined:
    Jun 29, 2017
    Posts:
    108
    Got a timeline on the guide? :)
     
  14. andrew210

    andrew210

    Joined:
    Apr 23, 2014
    Posts:
    241


    So here's the movement of players after converting it to work with Smartfox, are these issues things you have experience with before and could advise to a fix?
     
  15. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    590
    @andrew210
    Yeah, that doesn't look right at all. Since people seem to be asking for it, I'm just going to look into converting it for one of the solutions and then have a nice guide to share. I'll have it up by the end of the week. Maybe give me a screenshot of your Smooth Sync settings though, just in case you have wacky settings.

    @logixworx
    A few people are asking about converting it now so I'll do it by the end of the week. :)
     
  16. TiToMoskito

    TiToMoskito

    Joined:
    Jan 28, 2014
    Posts:
    66
    Is it possible to sync more than one child?
     
  17. Irye

    Irye

    Joined:
    Feb 17, 2017
    Posts:
    4
    hi,

    It also occurs when creating a prefab registered in "NetworkManager" without using "Object Pool".


    In that case, the Prefab is not checked for Server and Local permissions.
     
  18. SpindizzyGames

    SpindizzyGames

    Joined:
    Jun 29, 2017
    Posts:
    108
    Fuestrine - how about a writing an abstraction template rather than converting it for one solution?
     
  19. CleverEndeavour

    CleverEndeavour

    Joined:
    Mar 4, 2016
    Posts:
    12
    Could you write some details on how to use the teleport() function? I don't quite understand how or why to use the NetworkTimeStamp.
     
  20. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    590
    @Rexima
    Yes, it is possible to sync more than one child. Just add another SmoothSync component to the parent object and have it tracking a child object. This is able to be done for as many child objects as you want.

    @CleverEndeavour
    Good catch. I didn't realize I left that method uncommented. Take a look at the PlayerController.cs from the example scene for the full example but I'll describe it here.
    Call Teleport(timestamp, position, rotation) to teleport an object to that position and rotation. This must be called on the object on all computers on the network.
    So you can call Teleport() locally for instant movement on the owner, and then send the timestamp, position, and rotation over the network so that it can call Teleport() locally on all computers. The network time stamp is used so that it knows when it was teleported so that it can continue with interpolation and extrapolation as normal.

    @logixworx
    That's hopefully what I'll be ending up with when I get it all figured out again.
     
    Last edited: Nov 10, 2017
  21. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    590
    @Irye
    Isn't that how we are spawning objects in the example scene? I don't think I'm understanding correctly.
    You must then use GetComponent<NetworkIdentity>().AssignClientAuthority(conn) in order to assign server or client ownership is I believe your problem. If you uncheck localPlayerAuthority on the Network Identity, the server will be the owner automatically. Let me know if I'm not understanding correctly.
     
  22. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    590
    @logixworx @andrew210
    OK, so this is for Photon but the idea is pretty general. It's just converting it all to a byte array and then sending it however you would send it in your networking system. Then it receives the byte array and does some casts and then adds it to the states so Smooth Sync can use it. Let me know if you have questions or problems.

    Code (CSharp):
    1. public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    2.         {
    3.             // When sending data.
    4.             if (stream.isWriting)
    5.             {
    6.                 NetworkState newState = new NetworkState(this);
    7.                 NetworkWriter netWriter = new NetworkWriter();
    8.                 newState.Serialize(netWriter);
    9.                 // Sending the serialized byte array
    10.                 stream.SendNext(netWriter.AsArray());
    11.             }
    12.             // When receiving data.
    13.             else
    14.             {
    15.                 NetworkState networkState = new NetworkState(this);
    16.                 // Receiving the byte array
    17.                 object objectTemp = stream.ReceiveNext();
    18.  
    19.                 Byte[] byteArray = objectTemp as Byte[];
    20.                 NetworkReader netReader = new NetworkReader(byteArray);
    21.                 networkState.Deserialize(netReader, this.gameObject);
    22.  
    23.                 if (networkState != null && !networkState.smoothSync.netID.isMine)
    24.                 {
    25.                     networkState.smoothSync.adjustOwnerTime(networkState.state.ownerTimestamp);                
    26.                     networkState.smoothSync.restartLerping();
    27.                     networkState.smoothSync.addState(networkState.state);
    28.                 }
    29.             }
    30.         }
     
    Last edited: Sep 26, 2018
    nirvanajie and SpindizzyGames like this.
  23. SpindizzyGames

    SpindizzyGames

    Joined:
    Jun 29, 2017
    Posts:
    108
  24. andrew210

    andrew210

    Joined:
    Apr 23, 2014
    Posts:
    241
    Thanks for this!!
     
  25. Ice999va

    Ice999va

    Joined:
    Jan 2, 2017
    Posts:
    6
    Hi

    i have a problem i make a 2d game and every time when the game objects don't move they falling down and snap back how can i fix it ?
     
  26. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    590
    @Ice999va
    I don't get that happening in the example scene when I switch it to use 2D rigidbodies. Can you screenshot me your Smooth Sync script settings?
     
  27. Ice999va

    Ice999va

    Joined:
    Jan 2, 2017
    Posts:
    6
    @Fuestrine
    here a video, i hope you can help me !!!!!turne down the volume!!!!!!!
     
  28. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    590
    @Ice999va
    It says "This video is unavailable." You can try just uploading a screenshot to imgur.com or something if that's easier so I can see your Smooth Sync script settings.

    One idea I have for that happening, besides maybe the script settings, would be maybe you are setting gravity on non-owners when you should only be moving them on the object owner.
     
  29. Ice999va

    Ice999va

    Joined:
    Jan 2, 2017
    Posts:
    6
    @Fuestrine

    https://imgur.com/a/sYgwn

    so in rb 2d the gravity scale was on 1 now on 0 its away can you help me to tweak my settings its not perfect now wehn 2 Gameobjects collideis tons of space between them

    sry for my bad englisch ^^ hope you can help me
     
  30. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    590
    @Ice999va
    You shouldn't have to turn gravity scale to 0 to have it not fall through the floor. I just tested with your settings in the Smooth Sync Example scene and I don't get anything falling through the floor even with gravity scale on 1.

    EDIT: I'll get back to you on the space between objects.

    Let me know if you have any questions or if you are still getting the falling through the floor problem.
     
    Last edited: Nov 21, 2017
  31. Jick87

    Jick87

    Joined:
    Oct 21, 2015
    Posts:
    124
    @Fuestrine Quick question...

    Do you need to use child syncing for any child of an object you want synced? Or only for children that have their own rigidbody?

    For example, I have several objects in my scene that have several child colliders to make up a compound collider. The child colliders don't have a rigidbody, only the parent does. Do I need to use the child syncing function of Smooth Sync in that case?

    [EDIT] Oh, one other question... Does Smooth Sync handle pre-existing scene objects correctly? As in, objects that have a network identity and the Smooth Sync script but are built into the scene rather than instantiated in custom code?

    Thanks!
     
    Last edited: Nov 22, 2017
  32. Irye

    Irye

    Joined:
    Feb 17, 2017
    Posts:
    4
    Hi,
    Please refer to this video and project file.

    In your example, we have added a script that creates a "GameObject".

    Each one is a client and a server. The server is not a host.

    your email
    contact@noblewhale.com

    The file was sent by mail.
     
  33. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    590
    @Jick87
    You only need to sync the children that change local position. I believe a child with a rigidbody doesn't make any sense conceptually since if gravity and forces act on it independently, it being a parent doesn't do anything in the current Unity system.

    Yes, preexisting scene objects work with Smooth Sync.
     
  34. Jick87

    Jick87

    Joined:
    Oct 21, 2015
    Posts:
    124
    @Fuestrine Thanks for the reply!

    One more question...

    Was the issue the person here had ever figured out? I'm currently getting the same errors when I test with Smooth Sync. I'm not doing anything unusual with spawning or anything. My custom network manager is based on the Unity network manager. Also, I'm not using navmesh or anything like that person.

    Thanks!
     
  35. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    590
    @Jick87
    I believe that was fixed. You are getting those same three errors? Screenshot or copy / paste me the errors if they are different. At the very least the line numbers should have changed.

    Does everything seem fine after that first error message when spawning?
     
  36. Jick87

    Jick87

    Joined:
    Oct 21, 2015
    Posts:
    124
    @Fuestrine Here are the errors:
    Also, yes, everything seems to be working even with the errors.

    Thanks!
     
    Last edited: Nov 22, 2017
  37. ThoZ

    ThoZ

    Joined:
    Apr 21, 2013
    Posts:
    29
    Hey,

    We are trying to have all physics calculated on an authorative server.
    So we just send the input the server, he calculates next step, and synchronizes the new positions to the clients.

    So we just need smothSync to Sync from Server->Client.
    But it sends both ways.

    Is there a way to turn this of?

    Thank you.
     
  38. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    590
    @ThoZ
    If the server owns the object, it will just send from Server -> Client. If you are wanting to send commands on the object, then you would make another object that you own that you can send commands on, and then do whatever to the server owned object.
    Let me know if you need clarification or if I misunderstood your question.
     
  39. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    590
    @Jick87
    I added a null check there and will be pushing it in the next release. Thanks for the information.
     
  40. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    590
    @Ice999va
    The space between the objects is just going to happen. It's basically because things aren't going to be in the exact position on two computers across the country like they would be if it was all on one computer. If you want perfect reaction collisions between objects you are going to have to have them all be owned and ran on the same computer, probably the server. A lot of games get around this by having an authoritative server or sending the force of the collision on an RPC.
    Another way, and I don't recommend this at all, is you can switch setPosition() to set the position directly instead of using rb.MovePosition(). Check out the code below:
    Code (CSharp):
    1. public void setPosition(Vector3 position, bool isTeleporting)
    2.         {
    3.             if (hasChildObject)
    4.             {
    5.                 realObjectToSync.transform.localPosition = position;
    6.             }
    7.             else
    8.             {
    9.                 if (hasRigdibody && !isTeleporting)
    10.                 {
    11.                     rb.transform.position = position;
    12.                     //rb.MovePosition(position);
    13.                 }
    14.                 if (hasRigidbody2D && !isTeleporting)
    15.                 {
    16.                     rb2D.transform.position = position;
    17.                     //rb2D.MovePosition(position);
    18.                 }
    19.                 else
    20.                 {
    21.                     realObjectToSync.transform.position = position;
    22.                 }
    23.             }
    24.         }
    This makes it like Network Transform but it is basically just the wrong way to do it. All collisions this way are random and are just because the position gets set to be inside of another object and then things go crazy trying to get the object out of the other object and that's where the "collisions" come from.

    Let me know if you have more questions or if I misunderstood your problem.
     
    Last edited: Nov 24, 2017
  41. Jick87

    Jick87

    Joined:
    Oct 21, 2015
    Posts:
    124
    Oh, sounds great! Thanks so much! :)
     
  42. fmelogno

    fmelogno

    Joined:
    Oct 2, 2016
    Posts:
    24
    Hello, yesterday I bought Smooth Sync and I have a small problem. In two scenarios they work well.

    Work well in a single player of course and in the host server, too.

    On the dedicated server do not work for the player, yes for the enemies. The enemies exist in the server and spawn to the clients, this work.

    For player, spawn with clientauthority works in the client side with authority but not for the rest of clients.

    My old own code that works for the player's movements is:

    Code (CSharp):
    1. private Transform myTransform;
    2.  
    3.     [SerializeField] float lerpRate = 5.0f;
    4.  
    5.     [SyncVar] private Vector3 syncPos;
    6.  
    7.     //    private NetworkIdentity theNetID;
    8.  
    9.     private Vector3 lastPos;
    10.  
    11.     private float threshold = 0.065f;
    12.  
    13.  
    14.  
    15.     bool initialized;
    16.  
    17.     public void Init() {
    18.  
    19.         myTransform = GetComponent<Transform> ();
    20.  
    21.         syncPos = GetComponent<Transform>().position;
    22.  
    23.    
    24.  
    25.         initialized = true;
    26.  
    27.     }
    28.  
    29.  
    30.  
    31.     void FixedUpdate () {
    32.  
    33.         if(initialized) {
    34.  
    35.             TransmitPosition ();
    36.  
    37.             LerpPosition ();
    38.  
    39.         }
    40.  
    41.     }
    42.  
    43.     void LerpPosition () {
    44.  
    45.         if (!hasAuthority) {
    46.  
    47.             myTransform.position = Vector3.Lerp (myTransform.position, syncPos, Time.deltaTime * lerpRate);
    48.  
    49.         }
    50.  
    51.     }
    52.  
    53.     [Command]
    54.  
    55.     void Cmd_ProvidePositionToServer (Vector3 pos) {
    56.  
    57.         syncPos = pos;
    58.  
    59.     }
    60.  
    61.     [ClientCallback]
    62.  
    63.     void TransmitPosition () {
    64.  
    65.         if (hasAuthority  && Vector3.Distance(myTransform.position, lastPos) > threshold) {
    66.  
    67.             Cmd_ProvidePositionToServer (myTransform.position);
    68.  
    69.             lastPos = myTransform.position;
    70.  
    71.         }
    72.  
    73.     }
    Thanks..

    Federico Melogno
     
  43. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    590
    @fmelogno
    I don't think it has anything to do with the way you move it around.

    It works for me in the example scene when I run a dedicated server. "Server only" button.

    One idea I have for it not working is client authority isn't correctly assigned. You can use GetComponent<NetworkIdentity>().AssignClientAuthority(conn) in order to assign server or client ownership. If you uncheck localPlayerAuthority on the Network Identity, the server will be the owner automatically.

    Let me know if you have questions or if I misunderstood your problem. If you still have problems, let me know how you are spawning or send me a small project (preferably the example scene modified) and it will help me better track down your issue.
     
  44. fmelogno

    fmelogno

    Joined:
    Oct 2, 2016
    Posts:
    24
    Thanks for the response.
    I did it work when i changed:

    Code (CSharp):
    1. /// <summary>Send the owner's state over the network every 1 / sendRate seconds</summary>
    2. void Update()
    3. {
    4. if (!hasAuthority || (!NetworkServer.active && !ClientScene.ready)) return;
    with :

    Code (CSharp):
    1. if (!hasAuthority) return;
     
  45. Determined

    Determined

    Joined:
    Mar 22, 2013
    Posts:
    2
    @Fuestrine, looks like a great plugin. Just to make sure, does this work with the UNet Lobby Manager found in the asset store?
     
  46. Jick87

    Jick87

    Joined:
    Oct 21, 2015
    Posts:
    124
    @Determined I am actually using the Lobby Manager (albeit highly modified), so I would say it works just fine, for me at least. :)
     
  47. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    590
    @Determined
    I don't see why it wouldn't work with any UNET solution, and I haven't been told it doesn't work yet with any UNET solution yet.
     
    Last edited: Dec 1, 2017
  48. eco_bach

    eco_bach

    Joined:
    Jul 8, 2013
    Posts:
    1,601
    This works!!! Support is great. Question is, why is HLAPI so broken that it needs the support of these great 3rd party assets?
     
  49. Jick87

    Jick87

    Joined:
    Oct 21, 2015
    Posts:
    124
    @eco_bach My understanding is, the guy who did all the work on the HLAPI doesn't work at Unity anymore, and they haven't brought on anyone to replace him for some reason. So the only thing they are actively working on right now is the LLAPI, which definitely sucks. I guess most "serious" developers hire someone to code custom network stuff for them, which isn't too great for us hobbyists/n00bs. :p
     
  50. Paradoks

    Paradoks

    Joined:
    Oct 13, 2009
    Posts:
    436
    Hello, did a little mistake, i was pretty sure you wrote that it was synchronizing character controller...
    So i bought your plugin, now i am stuck as you obviously never wrote that :D
    will you make it work on character controller too ?