Author Topic: AutoSync  (Read 2520 times)

krvc

  • Newbie
  • *
  • Thank You
  • -Given: 4
  • -Receive: 0
  • Posts: 16
    • View Profile
AutoSync
« on: September 19, 2016, 02:13:00 PM »
Hi. My players have mouse click movement system.



  1. using UnityEngine;
  2. //using System.Collections;
  3. using TNet;
  4.  
  5.  
  6.  
  7.  
  8. public class Movement : TNBehaviour {
  9.     NavMeshAgent nav;
  10.    
  11.  
  12.     // Use this for initialization
  13.     void Start () {
  14.  
  15.        
  16.         nav = GetComponent<NavMeshAgent>();
  17.     }
  18.  
  19.  
  20.  
  21.  
  22.     // Update is called once per frame
  23.     void Update () {
  24.  
  25.         if (tno.isMine)
  26.         {
  27.             Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
  28.             RaycastHit hit;
  29.         if (Physics.Raycast(ray, out hit, 50000)&& Input.GetMouseButtonDown(0))
  30.  
  31.         {
  32.             nav.SetDestination (hit.point);
  33.    
  34.         }
  35.         }
  36.     }
  37. }


Players movements have lags. I added AutoSync.
My question -
larger values "Updater per second" (>50 for example) its good or not? Or maybe have better way?

cmifwdll

  • Global Moderator
  • Sr. Member
  • *****
  • Thank You
  • -Given: 0
  • -Receive: 149
  • Posts: 285
  • TNet Alchemist
    • View Profile
Re: AutoSync
« Reply #1 on: September 19, 2016, 04:24:14 PM »
It's possible your Update() loop is causing an FPS decrease. I believe Physics.Raycast expense increases with distance, and NavMeshAgent.SetDestination is rather expensive as well (it's been a while since I benchmarked it though). I made some optimizations here (won't fix the jittery movement though, more on that later):
  1. void Update()
  2. {
  3.         if (Input.GetMouseButtonDown(0))
  4.         {
  5.                 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
  6.                 RaycastHit hit;
  7.                 // 500f might still be too much, adjust as needed
  8.                 if (Physics.Raycast(ray, out hit, 500f)
  9.                 {
  10.                         float distance = nav.destination.DistanceTo(hit.point, true);
  11.                         // adjust the 1f as needed
  12.                         if (distance > 1f)
  13.                         {
  14.                                 if (!nav.SetDestination(hit.point))
  15.                                 {
  16.                                         Debug.LogWarning("Could not find valid path to target");
  17.                                         return;
  18.                                 }
  19.                         }
  20.                 }
  21.         }
  22. }
  23.  

You'll need this extension method:
  1. public static class ExtensionMethods
  2. {
  3.         // credit: Unity Engine
  4.         public static float DistanceTo(this Vector3 a, Vector3 b, bool ignoreHeight = false)
  5.         {
  6.                 Vector3 vec3 = new Vector3(a.x - b.x, a.y - b.y, a.z - b.z);
  7.                 if (ignoreHeight)
  8.                         vec3.y = 0f;
  9.                 return Mathf.Sqrt((float)((double)vec3.x * (double)vec3.x + (double)vec3.y * (double)vec3.y + (double)vec3.z * (double)vec3.z));
  10.         }
  11. }
  12.  

Making networked movement appear smooth is quite difficult and depends a lot on your specific needs. The AutoSync script is included more as an example than a final solution. It's always been recommended that you write your own movement code. Here are the two major approaches:
1. Sync input
   * In your case, you could sync every button click (with rate limiting to avoid those ultra-fast clickers :))
2. Sync the transform (this is what the AutoSync script does, but in the least efficient way :P)
   * Deltas (sync only what has changed and the amount it changed)
   * Float compression (this comes with a loss of precision, but in most cases not significant. 4 bytes reduced to 1 byte)
   
In both cases you'll have to deal with ping (this is what causes the jittery appearance). Easiest way to solve this is interpolating between movement updates. Aren has explained this really well, so I'll just paste those links here:
http://www.tasharen.com/forum/index.php?topic=6538.msg33291#msg33291
The LagPosition script (that performs the interpolation) can be found here:
http://www.tasharen.com/forum/index.php?topic=11830.msg54898#msg54898

In short you'll want to split your networked objects into two parts: the "real" transform, and the "display" transform. From a user perspective, you'll be seeing the "display" transform. The "display" transform is constantly chasing after the "real" transform via linear interpolation. The "real" transform is what receives and processes the movement update.

krvc

  • Newbie
  • *
  • Thank You
  • -Given: 4
  • -Receive: 0
  • Posts: 16
    • View Profile
Re: AutoSync
« Reply #2 on: September 22, 2016, 01:48:13 AM »
Ok. Thanks. I use it.
My C# knowlege is very low, sorr for my questions.