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

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

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

  1. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    587
    @MostHated
    Ah. You could try taking out the gravity in extrapolation. Line 915ish of SmoothSync. Comment out everything in between the // Gravity and the // Drag.
     
  2. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    1,235
    I will give that a try. So strange that it worked just fine for the video but then next time I started it, it didn't. I will be sure to try some more stuff once I finish all my work-related things.
     
  3. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    1,235
    I wonder if this has something to do with it. I was using HLAPI Pro replacement DLL's for Unity, I was using only the 2017.3 "Fix" version not the "Fix and Improvement" one, but it turns out the dev just told me that the fix version has the below built in it.. I would venture to guess that, that is what was causing the funkyness. Though, I am not 100% sure, since I was not using the Unity Network Transform component, unless of course your is tying into it in anyway, if it is, and things are different within it from the normal one, that could account for it acting weird. It says it would require no code changes though, which is why I am wondering if it matters or not.

    [2017-08-05] NetworkTransform reimplemented from scratch
    • Problem: NetworkTransform was bloated with lots of components, all together 2144 lines of code. No interpolation. No NavMeshAgent consideration. High and Low compression modes did the same. No distinction between Kinematic and nonKinematic Rigidbodies. Too many computations.
    • Solution: reimplemented it from scratch. 300 lines of clean and simple code. Transform/Rigidbody2D/Rigidbody3D/NavMeshAgent support (including Kinematic Rigidbodies). Interpolation. 4 compression modes, able to squeeze a Rotation into 2 bytes and still work. Teleport detection. Great Gizmo makes it easy to debug.
     
    Last edited: Mar 20, 2018
  4. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    587
    @MostHated
    I'm not using NetworkTransform at all in SmoothSync. Switching out the networking dlls does sound kind of scary though.
     
  5. Alkanov

    Alkanov

    Joined:
    May 15, 2017
    Posts:
    54
    Hi,

    How can I use this asset with an authoritative server? From what I understand, mobile players, can easily increase their cpu tick rate and make a speed hack out of this.

    I feel like I am missing an important part here.

    Thanks.
     
  6. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    587
    @Alkanov
    You would use it just like you would with Unity's NetworkTransform except instead of adding NetworkTransform to your object, you add SmoothSync. Make an authoritative server and spawn the objects as normal. Unchecking LocalPlayerAuthority on Unity's NetworkIdentity on the object will make the object owned by the server.
     
  7. Alkanov

    Alkanov

    Joined:
    May 15, 2017
    Posts:
    54
    Right, but doesnt this means that there is still a lot to do for the client movement to feel quicky responsive? Otherwise clients will have to wait for RTT to see their movement.

    Please correct me if I'm wrong.
     
  8. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    587
    @Alkanov
    Correct. We do not do any kind of player prediction.
     
  9. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    1,235
    That, unfortunately, didn't do anything to help. I think I am just done messing around with it. Using the rewritten one from HLAPI Pro works just fine, so I will probably just stick with that for now. I appreciate the help though. If I keep messing with this anymore I am going to end up just throwing my computer out the window and deleting my project.
     
  10. Alkanov

    Alkanov

    Joined:
    May 15, 2017
    Posts:
    54
    Right. Are you planning to work on this? You would potentially be the only one in the asset store offering such thing. I would pay up to 50 bucks just for that module

    Maybe release it as an add-on to this one?
     
  11. chiapet1021

    chiapet1021

    Joined:
    Jun 5, 2013
    Posts:
    605
    From what I understand, client side prediction for rigidbodies is a terribly difficult problem to solve in Unity currently. Since the vast majority of character controllers use rigidbodies, they are thus stuck with this same challenge.
     
    Fuestrine likes this.
  12. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    587
    @Alkanov
    I have no plans to work on any client side prediction. I think about it every now and then but nothing is planned.
     
  13. Alkanov

    Alkanov

    Joined:
    May 15, 2017
    Posts:
    54
    We all know you want to do it :), so why not?

    Also, you could start with just simple client/server movement sync, leave physics aside. I tell you this because I am developing a 2d top down game and it doesn't involve physics at all (maybe just collision against walls and simple stuff) so i'm sure that many here would use this asset.

    With as little as allowing the client to move his own object + sending controller commands to server + moving object in server + some sort of reconciliation in case of lag (if pos in server is too different) it would suffice.
     
  14. chiapet1021

    chiapet1021

    Joined:
    Jun 5, 2013
    Posts:
    605
    I feel like non-rigidbody use cases are too rare for it to be worth it for Fuestrine's asset. I would anticipate customers being under the false impression that his client side prediction would/should work for rigidbody controllers, then be disappointed/angry when that impression is corrected. Unjustified bad reviews would follow, etc etc.

    Perhaps after this little gem happens, client side prediction will be easier: https://forum.unity.com/threads/calling-the-physics-simulation-from-c.444659/page-3#post-3422818
     
  15. pan4ezzz

    pan4ezzz

    Joined:
    Jul 9, 2017
    Posts:
    19
    Asset works correctly only on authoritative server?

    I need sync ball in p2p, ignore who is server.

    1) Have ball with "Local Player Authority" flag;
    2) Assign authority for local player;

    Code below in ball gameObject:


    if (player.isLocalPlayer) // player - link to local player gameObject
    {
    if (Input.GetKeyUp(KeyCode.T))
    Trow(Random.Range(100, 300));
    }

    //isLocalPlayer only
    void Trow(int _force)
    {
    // Player and ball have different positions and i need to sync start positions and addforce in one frame
    // in original code ball visibility hide and show fake object in child of player on all clients to save bandwidth
    var timestamp = NetworkTransport.GetNetworkTimestamp();
    smoothSync.teleport(timestamp, fake.transform.position, fake.transform.rotation);

    var f = userRigidbody.rotation * throwForce * _force;
    r.AddForce(f);

    CmdForce(timestamp, fake.transform.position, fake.transform.rotation, f);
    }

    [Command]
    void CmdForce (int _timestamp, Vector3 _pos, Quaternion _rot, Vector3 _f)
    {
    smoothSync.teleport(_timestamp, _pos, _rot);
    r.AddForce(_f, forceMode);

    RpcTeleport(_timestamp, _pos, _rot, _f);
    }

    [ClientRpc]
    void RpcTeleport(int _timestamp, Vector3 _pos, Quaternion _rot, Vector3 _f)
    {
    if (hasAuthority) return;
    smoothSync.teleport(_timestamp, _pos, _rot);
    r.AddForce(_f, forceMode);
    }


    In this implementation, I need to start the teleport and AddForce 3 times:
    - for local client
    - for the server
    - for other customers

    This can cause visual bugs when the network is delayed.
    How to do it correctly?
     
  16. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    587
    @Alkanov
    I do but I certainly wouldn't be waiting on me for it. :)

    @Pan4ezzz
    It looks like you are trying to add force to the same object on both the owner and non-owner. You will only want to affect the movement on the owner which will then automatically make it look the same on all non-owners. Let me know if I misunderstood your problem.
     
  17. pan4ezzz

    pan4ezzz

    Joined:
    Jul 9, 2017
    Posts:
    19
    Yes exactly!
    I have to imitate add force in all instances because the code below does not work


    if (player.isLocalPlayer) // player - link to local player gameObject
    {
    if (Input.GetKeyUp(KeyCode.T))
    Trow(Random.Range(100, 300));
    }
    //isLocalPlayer only
    void Trow(int _force)
    {
    // Player and ball have different positions and i need to sync start positions and addforce in one frame
    // in original code ball visibility hide and show fake object in child of player on all clients to save bandwidth
    var timestamp = NetworkTransport.GetNetworkTimestamp();
    smoothSync.teleport(timestamp, fake.transform.position, fake.transform.rotation);

    var f = userRigidbody.rotation * throwForce * _force;
    r.AddForce(f);
    }
     
  18. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    587
    @Pan4ezzz
    What doesn't work about it? Nothing is happening at all? It's not smooth on the non-owners? It only moves on the owner but not the non-owners?
     
  19. pan4ezzz

    pan4ezzz

    Joined:
    Jul 9, 2017
    Posts:
    19
    nothing, addforce from isLocalPlayer with hasAuthority does not work for anyone and for himself
     
  20. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    587
    @Pan4ezzz
    It sounds like you are having ownership issues. Does it work if you switch out the SmoothSync.cs with Unity's Network Transform?
     
  21. pan4ezzz

    pan4ezzz

    Joined:
    Jul 9, 2017
    Posts:
    19
    maybe, unity physics is ugly, thanks for trying to help
     
  22. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    587
    @Pan4ezzz
    If it works with Network Transform then it's probably a problem with Smooth Sync. Let me know the steps to recreate the issue or I'd also be happy to just take a look at your project if Network Transform works but Smooth Sync doesn't.

    If it doesn't work with Network Transform then it's probably just something fundamentally wrong in how you are spawning and trying to do things. I can answer some specific questions on this but networking is a large and complex issue and I can't think of anything specifically right now that would help without more information.
     
  23. pan4ezzz

    pan4ezzz

    Joined:
    Jul 9, 2017
    Posts:
    19
    Today with a fresh mind. The problem is true in Smooth Sync.

    In short, what am I doing with NetworkTransform:
    Code (CSharp):
    1.  
    2. void Start()
    3. {
    4.     if (isLocalPlayer)
    5.     {
    6.         CmdAuthority(go);
    7.     }
    8. }
    9.  
    10. [Command]
    11. void CmdAuthority(gameObject _go)
    12. {
    13.     _go.GetComponent<NetworkIdentity>().AssignClientAuthority(connectionToClient);
    14. }
    15.  
    16. void Update()
    17. {
    18.     if (isLocalPlayer && Input.GetKey(KeyCode.T))
    19.     {
    20.         var r = go.GetComponent<Rigidbody>();
    21.      
    22.         if (!isServer)
    23.             CmdTrow(go);
    24.  
    25.         r.AddForce(force, forceMode);
    26.         }
    27.     }
    28. }
    29.  
    30. [Command]
    31. void CmdTrow(GameObject _go)
    32. {
    33.     if (isLocalPlayer) return;
    34.     _go.GetComponent<Rigidbody>().AddForce(force, forceMode);
    35. }
    36.  
    This works for all directions:
    Client > Clients
    Server > Clients
    Client > Server

    If I use Smooth Sync works only:
    Client > Clients
    Server x Clients
    Client > Server

    SmoothSync and NetworkTransform with the default options
     
  24. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    587
    @Pan4ezzz
    I just have more questions now and I think it'll be easier to figure out if you can send me your project. Is this possible? I'll send you the support email in a PM, or you can just PM me a dropbox link or whatever on here.
     
    Last edited: Mar 26, 2018
  25. Jick87

    Jick87

    Joined:
    Oct 21, 2015
    Posts:
    124
    What would be the reason for getting this error in the logs when testing?:
    It seems to point to line 417 of State.cs, but I'm not sure what exactly could be causing it...

    Thanks!
     
  26. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    587
    @Jick87
    Does it happen once per object at the beginning or all of the time? If it's just once per object at the beginning, ignoring it should be fine. I never was able to track down why that happens for some people. You can comment out that warning if it's getting in the way.

    If you've got a smallish organizedish project where that happens and want to send it my way to the support email or PM me a dropbox link or whatever, I'd be happy to finally try to see what the real reason for that happening for some people is.
     
  27. pan4ezzz

    pan4ezzz

    Joined:
    Jul 9, 2017
    Posts:
    19
    This is a special case in a large and very raw project, I specifically described all the actions.
    Would be cool to get a demo with all the action on behalf of isLocalPlayer, not from hasAuthority.
     
  28. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    587
    @Pan4ezzz
    I can't really get the full picture from your provided code. How are you spawning?
     
  29. pan4ezzz

    pan4ezzz

    Joined:
    Jul 9, 2017
    Posts:
    19
    @Fuestrine, everything works great, it's my fault

    I remove "RemoveClientAuthority" after AddForce() and it worked, it is important, probably
    Everything is sync from localPlayer with authority without command
     
  30. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    587
    @Pan4ezzz
    Great to hear. Let me know if you have any other problems.
     
  31. Contiinuum

    Contiinuum

    Joined:
    Jun 24, 2017
    Posts:
    6
    Hey there! I bought Smooth Sync yesterday and I'm really happy with it so far! I did run into one issue tho.
    With smooth sync attached, when a client shoots, the ball appears but doesn't move neither on the client itself nor on the host.
    If I attach a NetworkTransform component and disable it and keep smooth sync attached, the ball moves correctly on all connected players (but doesnt actually seem to be moved thorugh smooth sync).
    Here's the code I use for spawning:
    Code (CSharp):
    1.  
    2. [Command]
    3. private void CmdSpawnBall(Vector3 direction, Vector3 pos, float playerSpeed)
    4. {
    5.     GameObject go = Instantiate(ballPrefab, pos, Quaternion.identity) as GameObject;
    6.     go.transform.LookAt(direction);
    7.     go.GetComponent<Rigidbody>().velocity = direction * (ballSpeed + playerSpeed * .5f);
    8.     NetworkServer.SpawnWithClientAuthority(go, connectionToClient);
    9. }
    10.  
    Now I see you suggested using
    GetComponent<NetworkIdentity>().AssignClientAuthority(conn)
    which I tried aswell. When I do that, the ball syncs with smooth sync but doesn't move on the client who shot it.
    I really don't know what the issue might be so I'd be very thankful if you could help me!
    Thanks.

    edit: just got it working: using
    NetworkServer.SpawnWithClientAuthority(go, NetworkServer.connections[0]); 
    solved the issue.
     
    Last edited: Apr 7, 2018
  32. sun_stealer

    sun_stealer

    Joined:
    Oct 4, 2016
    Posts:
    24
    Hello! I purchased the asset, and so far it seems like a great one. At least server->client sync looks better than with default NetworkTransform.

    But I got stuck on one thing today, and I really could use an advice.
    I'm building an Oculus VR game where players (clients) can pick up certain objects and move them around. Say, small boxes with BoxCollider and RigidBody.
    I use standard OvrGrabber script to pick up objects with virtual hands, which internally uses RigidBody.MovePosition to move the object. It works great on the server and on the client locally, but the changes are not propagated from client to server. I thought I needed to set NetworkIdentity LocalPlayerAuthority to true and claim the object ownership when I grab an object on a client. But if I do that, objects start to glitch all over the place, like if the physics updates are applied on both server and client and they are in conflict or something. I obviously need only one copy of the physics process running for these objects.

    @Fuestrine how should I deal with this scenario? Is there a tutorial that shows a synced movement of physical rigid bodies on both server and client?
     
  33. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    587
    @sun_stealer
    Hi! Sorry about the issue.
    At first I would try to switch out the SmoothSync component with NetworkTransform and if it still doesn't work then it's probably something funky going on that isn't SmoothSync.

    If you are changing authority a lot, you'll need to clear a buffer too or it'll take a bit to catch up. There's a smallish example in the example scene on SmoothSyncExamplePlayerController.cs that may relieve your issues. I'll paste the super relevant bits here:
    You'll need to call CmdClearBuffer() to clear the buffer on all instances. You'll probably want to do NetworkIdentity.AssignClientAuthority(conn) and these Cmds and Rpcs on a separate object that's always owned by the server so that there's no ownership changes of an object while you are trying to send these Cmds and Rpcs.

    If that's not your problem, let me know how you are spawning your objects and screen shot me your Network Identity and Smooth Sync components for the object that isn't working so I can try to recreate the issue.
     
    sun_stealer likes this.
  34. sun_stealer

    sun_stealer

    Joined:
    Oct 4, 2016
    Posts:
    24
    Hi @Fuestrine, thank you very much for the hints.
    I actually spent the last few hours putting together a small Unity project to isolate my issues, and I more or less got it working even with NetworkTransform. The accurate transfer of the ownership and high "rotation interpolation" value (30 instead of default 1) are keys.

    Still, I better like how the physics synchronization works with SmoothSync. So far I just replaced NetworkTransforms in my example with SmoothSync, and out-of-the-box it almost works, except when ownership is transferred on some objects they stay in the same place on the client. I don't have time to look at it now, will try to find the issue tomorrow. The console is filled with "Received state out of order for: capsule_s(Clone)"

    Link to the sample project: https://drive.google.com/open?id=1RHk2wUmeHOwoWpsfQf_L8_fAmDLKI6kE
    The scene sync_rigidbodies works rather well, but in the scene sync_rigidbodies_smoothsync there's this glitch.
    If you could have a quick look and give me a hint, that would be very helpful. Otherwise, I'll try to find myself tomorrow.
    To run the sample you should import SmoothSync plugin, and then click on objects to drag them around with LMB.
     
  35. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    587
    @sun_stealer
    I don't have any objects spawning in the SmoothSync scene and they only seem to spawn when the editor is the host in the NetworkTransform scene (not at all on client).

    It sounds like you just need to do the CmdClearBuffer() thing that I was saying though. It's going to have to wait the amount of time between when you started the two game instances unless you do that. If it never starts moving again even after the amount of time, then it's probably not the issue, but you'll be wanting to call CmdClearBuffer() anyway so you might as well get that out of the way now.

    If that doesn't work, feel free to link me again to a newer project or let me know if I need to do anything different to get objects to spawn. I imported SmoothSync and it all looked hooked up fine.
     
    Last edited: Apr 18, 2018
  36. sun_stealer

    sun_stealer

    Joined:
    Oct 4, 2016
    Posts:
    24
    Okay, I figured Unity does not like when you open a project with some components when you don't yet have them. The component on a prefab is displayed as "missing script" which does not fix itself when I import SmoothSync from Asset Store. Anyway, I packaged this sample project with your plugin and sent you a link via PM.

    Here's a short demonstration of the problem:

    When I move the capsule from the client, it syncs on server, but when I transfer ownership back to server, it does not move on the client. The exact same code with NetworkTransform works.
    Should really go to sleep now. Thanks for helping me! Will look at this tomorrow, hopefully your suggestion helps.
     
  37. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    587
    @sun_stealer
    I'm syncing fine in the SmoothSync scene you provided so I'm not really sure what's going on. I can drag items on either the host or the client and have it show on the other window. One thing I did notice was that you sent me a 5.6 Unity version first and a 2017.4 Unity version next so maybe you have something going on with using a different editor? I used the latest version that's on the Unity page to open your project.
     
  38. sun_stealer

    sun_stealer

    Joined:
    Oct 4, 2016
    Posts:
    24
    @Fuestrine I tried on both 5.6 and 2017.4 - two different machines, it was exactly the same. Okay, something interesting is going on indeed. I'll report if I find anything
     
  39. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    587
    @sun_stealer
    Yes, let me know. It's definitely strange. I followed your video to recreate the issue and got no problem. I wish I could be of more help. The only idea I have is Time could be different in your editor and build so try CmdClearBuffer(), which you'll need to do anyway when changing authority.
     
    Last edited: Apr 19, 2018
  40. sun_stealer

    sun_stealer

    Joined:
    Oct 4, 2016
    Posts:
    24
    @Fuestrine
    I added CmdClearBuffer as you instructed, this didn't change much. I can confirm that this bug is erratic and does not reproduce 100% of the time. It seems to reproduce more often when I have a lot of objects (like 200), but still not every time.

    I logged the variables in SmoothSync.cs with this line:
    Debug.LogWarningFormat("Received state out of order for: {0} {1} {2} {3}", realObjectToSync.name, stateCount, state.ownerTimestamp, stateBuffer[0].ownerTimestamp);

    And when it reproduces the typical log output is:
    Received state out of order for: sphere_s(Clone) 2 63000 74012120

    Clearly, 74012120 is not a valid value for network timestamp. So it's either a glitch of NetworkTransport.GetNetworkTimestamp(); or the data is corrupted somewhere when the packet is transferred. BTW, I used two instances of the app on localhost for all my experiments. It may not reproduce over the regular network, I don't know.
     
  41. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    587
    @sun_stealer
    I think I got it figured out! It appears to be because sometimes it'll clear the buffer on the client before it actually receives and sets the authority change on the client.

    I'll be spending tonight coming up with a solution. It looks like I'll be able to do all the work in the background so you won't even need to call ClearBuffer() yourself anymore.

    Thanks for giving me a heads up about the problem. Hopefully I'll be able to upload a new version to the Asset Store tomorrow. I'll message you when I'm done in case you want it sooner instead of like a week later when Unity approves the asset for release.
     
    Last edited: Apr 20, 2018
    sun_stealer likes this.
  42. sun_stealer

    sun_stealer

    Joined:
    Oct 4, 2016
    Posts:
    24
    @Fuestrine wow, thanks for keeping up the great work! Yep, if you could send me the update, that would be helpful. I could try it over the weekend or on Monday. Thanks once more!
     
  43. Contiinuum

    Contiinuum

    Joined:
    Jun 24, 2017
    Posts:
    6
    Hey @Fuestrine,
    I'd really appreciate some help of yours.
    I'm trying to do an fps dodgeball game. Theres one rigidbody ball and 2 players. The ball's velocity gets set directly (no AddForce used). The players have the ability to either reflect the ball or pick it up and shoot it. Functionality wise, everything works as expected. However, I can't seem to find a good solution on how to make it feel responsive on clients. On hosts, velocity changes appear instantly and feel good, which makes sense. On clients, the ball jerks back and forth a bit when reflecting and when shooting the ball only starts moving again after a delay. I tried stopLerping(), applying the velocity locally, sending a command to the server with the velocity change and calling restartLerping() in the command function.
    It doesn't really change much tho, results are more or less the same.
    The host has authority over the ball.
    Is there anything I can do to make it better for clients?
     
  44. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    587
    @ContinuumRL
    Unfortunately we don't have any kind of "client side prediction" that's going to make it work out of the box. Smooth Sync will just track the movement from the owner and make it smooth.

    Your problem seems to be because your ball is owned by the server so it's really reflecting off the server version of the player, which is slightly different than the locally owned version. Lowering the InterpolationBackTime on your players should help make it more accurate but isn't going to fix the problem.

    One tip might be to take off the colliders on unowned objects. Another might be to instead of being a straight reflection, you would catch the ball and then shoot off an entirely different ball that's owned by the server or client in the direction a reflection would have gone but you mask it by making it a catch and release or something.

    Even AAA games have problems with interacting with an object and it taking a bit to update on your end so I wouldn't expect perfection but I do have some other random ideas for you if you want to get your hands dirty.

    You could have a bit of a pause on reflection and shooting. With any luck this will add some extra "oomph and juice" to your game anyway(look at games like Street Fighter with their pauses on hits).

    You could stop moving the ball locally when it hits the reflection point (on both server and client), wait for the server to get the message that you have hit the ball on the client (and maybe where, the server would then hit it back out based on the reflection angle provided by the client) and then wait for a message from the server back to the client to tell the client to start updating the object locally again. Maybe add some particles and glow during this pause to add juice.

    For shooting, you could also do a bit of a pause (arm wind up or something) before shooting. That way it'll line up visually.

    If there is a hard limit of two players, you could change the authority of the object as it heads over the middle into the other side. This will probably produce a visual hiccup though.

    I could also see some authority change thing on reflection and picking up a ball working. Or maybe you switch out the balls entirely on reflection and have one always owned by the server and one always owned by the client. Turn off the visualizations of the one and then you maybe have something?

    I have no guarantees on any of that, it's just my thoughts on the issue. In my game, I implemented the wait a bit before interacting with the object approach and I of which I've only done the one where you wait a bit before interacting in my game. Let me know if I rambled incoherently or if you have any questions.

    Here is an easy way to stop the SmoothSync object from updating position locally on the client using a newly added stopUnownedLocalTransformUpdate variable.

    Code (CSharp):
    1. public bool stopUnownedLocalTransformUpdate = false;
    2. void applyInterpolationOrExtrapolation()
    3.         {
    4.             if (stateCount == 0) return;
    5.  
    6.             if (stopUnownedLocalTransformUpdate == true) return;
    That seems to work fine. You'd have to do some lerping and stuff yourself though.
     
    Last edited: Apr 22, 2018
  45. Contiinuum

    Contiinuum

    Joined:
    Jun 24, 2017
    Posts:
    6
    @Fuestrine
    Thanks a lot for all of your input, I'll try your ideas and see how it turns out.
    Also, let me say the support you're giving in this thread alone is outstanding. Especially concidering your help regarding things that aren't related to SmoothSync.
    Take care!
     
    Fuestrine likes this.
  46. poshaughnessey

    poshaughnessey

    Joined:
    Jul 12, 2012
    Posts:
    45
    I was able to use Smooth Sync successfully on iOS, and am now trying to target HoloLens UWP, but I getting the following errors when building:

    Assets\Plugins\Smooth Sync\HalfHelper.cs(3,22): error CS0234: The type or namespace name 'Remoting' does not exist in the namespace 'System.Runtime' (are you missing an assembly reference?)
    Assets\Plugins\Smooth Sync\HalfHelper.cs(4,47): error CS0234: The type or namespace name 'Binary' does not exist in the namespace 'System.Runtime.Serialization.Formatters' (are you missing an assembly reference?)

    Not positive what build settings I'm missing to ensure those namespaces are included?
     
  47. sun_stealer

    sun_stealer

    Joined:
    Oct 4, 2016
    Posts:
    24
    Hi, @Fuestrine
    I understand that you've already spent a lot of time answering my questions, and I really appreciate your help. But unfortunately, I still wasn't able to solve all of my problems.
    The major issue that I have right now is a drastic difference in physical interactions between the server and the client. Please take a look at the video here:

    The left app is the server (host), the right one is the client. Objects are colored for debugging purposes: red means we own the object (hasAuthority) and we currently control it with the mouse, green means just hasAuthority = true, yellow means hasAuthority = false. When I move the mouse, the red controlled object is moved using rigidBody.movePosition.

    As you can see, when I move the cube on the left (host) the physics is smooth and predictable, but when I move the cube on the right, the interactions become really jerky. Non-owned objects seem like they're glued to the ground, and it's very hard to move them with the controlled object. I totally understand that physics will never be 100% the same on client and server, but I didn't expect this problem to be so severe. As I've found in the code, SmoothSync moves the remotely controlled objects with rigidBody.MovePosition (if they have a rigid body). So I expected the physics to be relatively okay.
    Keep in mind, this is a model example. In my real VR app users take objects with their hands and move them around, and the lack of realistic physical interaction on the client ruins the immersive VR experience.

    I tried these approaches so far to solve this issue:
    1) Change authority for all objects that surround the object controlled by the client. This solves the problem partially but introduces a lot of problems of its own, e.g. when 2 clients interact with more or less the same set of objects we need to change authority too often.

    2) Keep all objects on the server and only send the desired rigid body movement from client to server via UNET. This introduces big lag. With this it does not seem like we're holding the object in the hand anymore, it just floats in the air near the hand.

    3) Adding a fake object that we hold in the hand on the client does not help either, because physical interaction does not match the visual appearance of the object.

    @Fuestrine are there any settings that can help me in this scenario? I already have network send rate of 60 instead of 30, and it doesn't help much. I knew networking physics is difficult, but I had no idea I won't be able to get it working at least relatively okay. Is there anything that can solve this?
     
  48. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    587
    @poshaughnessey
    I don't appear to be utilizing either of those namespaces, interesting, I guess I just left them in on accident. Sorry about that. Take them out and let me know how it goes.
     
  49. Fuestrine

    Fuestrine

    Joined:
    Feb 13, 2013
    Posts:
    587
    @sun_stealer
    Your main problem is just a limitation of how things like Smooth Sync and Unity's Network Transform works. In a very basic sense, they both just send out the transform of the owner and relay it to non-owners.

    Sorry if I repeat points you already know but I'm going to give an overview here of my current understanding of the base problem.

    So you have an object owned the server and owned by the client.
    You shoot your server owned object at the client owned object. On the server side, the object will go to the contact point and then reflect off. Now this client owned object doesn't move on the server until it moves on the client. Well this is some difference in time and the ball has already reflected off. So the client side sees this server object come close to colliding with the client object but in a perfect scenario, the ball never actually collides since it's basically unmovable on the server unless the client tells it to move, and by then, the ball has already reflected off.
    So basically, the only way it works is when it's "erroring" out and trying to move inside the other ball, which is what your forcing the ball on the screen of the client will do. This isn't correct at all though because at the least it would just be determined by how fast it's currently lerping.

    Quick fixes would be changing WhereToUpdateTransform to Update instead of FixedUpdate. It will get it pushing harder against objects but that's only because it will literally be trying to place them inside each other and it will "bounce" out in very unpredictable ways.
    You can also lower the InterpolationBackTime which will make it closer to the present.
    I'm not sure what your final game is but you could rpc some AddForce() and have some type of delay animation for knocking objects around also.

    One way other games like Rocket League (I believe) solve this problem is by using a dedicated server and all objects are owned by the server. They have some sweet client prediction code for their cars and ball so it feels instant when you move but really it's just moving a car and ball on the server. Like if you hold gas for 3.14 seconds and turn left at 1.43 seconds in, it'll hold the gas for 3.14 seconds and turn left at 1.43 seconds on the server. It then checks your local position to make sure it's not too far off from the server and then corrects you (this is what people refer to as rubber banding when it becomes noticeable.)

    Let me know if I didn't make sense at all or I missed responding to anything or if you have any questions.
     
    Last edited: Apr 26, 2018
  50. Contiinuum

    Contiinuum

    Joined:
    Jun 24, 2017
    Posts:
    6
    Hello @Fuestrine,

    I used SmoothSync to sync children before - however, right now I'm trying to sync the localRotation of the player's arm. This arm is roughly a 4th level child (has 3 parents) and doesn't seem to sync. I don't know if I'm doing something wrong, or if this is a general problem. It doesn't work with Unity's NetworkTransformChild either.

    edit: I found the issue - animation. It does work locally without issues for some reason, but trying to change the rotation on clients while any animation using the same transform is running, it won't work.
     
    Last edited: Apr 27, 2018