Advertisement
Guest User

Untitled

a guest
Aug 21st, 2013
9
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. //Predictor script for client
  5. //with client side prediction
  6.  
  7. public class C_Predictor : MonoBehaviour {
  8.  
  9.     public float pingMargin = 0.5f;
  10.    
  11.     private float clientPing;
  12.    
  13.     private NetState[] serverStateBuffer = new NetState[20];
  14.    
  15.     private NetState[] clientStateBuffer = new NetState[20];
  16.    
  17.     //Keep track of what Slots are used
  18.     private int m_LocalStateCount;
  19.    
  20.     // Stat variabels for prediction stuff
  21.     private float m_TimeAccuracy = 0;
  22.     private float m_PredictionAccuracy = 0;
  23.     private bool m_FixError = false;
  24.     private Vector3 m_NewPosition;
  25.     private Quaternion m_NewRotation;
  26.    
  27.     // The position vector distance to start error correction. The higher the latency the higher this
  28.     // value should be or it constantly tries to correct errors in prediction
  29.     public float m_PredictionThreshold = 0.3F;
  30.  
  31.     // Time difference in milliseconds where we check for error in position. If the server time value
  32.     // of a state is too different from the local state time then the error correction comparison is
  33.     // highly unreliable and might try to correct more errors than there really are.
  34.     public float m_TimeThreshold = 0.05F;
  35.  
  36.    
  37.    
  38.     public void uLink_OnSerializeNetworkView(uLink.BitStream stream, uLink.NetworkMessageInfo info)
  39.     {
  40.         if(!stream.isWriting)
  41.         {
  42.             Vector3 pos = Vector3.zero;
  43.             Quaternion rot = Quaternion.identity;
  44.            
  45.             stream.Serialize(ref pos, 0.001f);
  46.             stream.Serialize(ref rot, 0.001f);
  47.            
  48.             //receiver.serverPos = pos;
  49.             //receiver.serverRot = rot;
  50.            
  51.             //smoothly correct client pos
  52.             //receiver.lerpToTarget(); //Bug lerp immediately the player to the final pos and with the interpolation the player return back
  53.            
  54.             //take care of data for interpolating remote objects movements
  55.             //Shift up the buffer
  56.             for(int i = serverStateBuffer.Length - 1; i >= 1; i--)
  57.             {
  58.                 serverStateBuffer[i] = serverStateBuffer[i - 1];   
  59.             }
  60.            
  61.             //Override the first element with the latest server info
  62.             serverStateBuffer[0] = new NetState((float)info.timestamp, pos, rot);
  63.            
  64.             /*int m_TimestampCount;
  65.             for(int i = 0; i < m_TimestampCount-1; i++)
  66.             {
  67.                 if(serverStateBuffer[i].timeStamp < serverStateBuffer[i + 1].timeStamp)
  68.                 {
  69.                     Debug.Log("State inconsistent");   
  70.                 }
  71.             }*/
  72.            
  73.         }
  74.        
  75.     }
  76.    
  77.     // Use this for initialization
  78.     void Start ()
  79.     {
  80.         StartCoroutine(StoreLocalMovement());
  81.     }
  82.    
  83.     IEnumerator StoreLocalMovement()
  84.     {
  85.         while(true)
  86.         {
  87.             yield return new WaitForSeconds(1/10);
  88.            
  89.             //shift buffer content
  90.             for(int i = clientStateBuffer.Length - 1; i >= 1; i--)
  91.             {
  92.                 clientStateBuffer[i] = clientStateBuffer[i - 1];   
  93.             }
  94.            
  95.             clientStateBuffer[0] = new NetState((float)uLink.Network.time, transform.position, transform.rotation);
  96.            
  97.             m_LocalStateCount = Mathf.Min(m_LocalStateCount + 1, clientStateBuffer.Length);
  98.            
  99.             //
  100.             //Check if the client side prediction has an error
  101.             //
  102.            
  103.             //Find the local buffered state which is closest to network state in time
  104.             int j = 0;
  105.             bool match = false;
  106.             for(j = 0; j < m_LocalStateCount - 1; j++)
  107.             {
  108.                 if(serverStateBuffer[0] != null)
  109.                 {
  110.                     if(serverStateBuffer[0].timeStamp <= clientStateBuffer[j].timeStamp && clientStateBuffer[j].timeStamp - serverStateBuffer[0].timeStamp <= m_TimeThreshold)
  111.                     {
  112.                         if(Debug.isDebugBuild)
  113.                         {
  114.                             //Debug.Log("Comparing state " + j + "localtime: " + clientStateBuffer[j].timeStamp  + " networktime: " + serverStateBuffer[0].timeStamp);
  115.                             //Debug.Log("Local: " + clientStateBuffer[j].pos + " Network: " + serverStateBuffer[0].pos);
  116.                         }
  117.                        
  118.                         //m_TimeAccuracy = Mathf.Abs(clientStateBuffer[j].timeStamp - serverStateBuffer[0].timeStamp);
  119.                         m_PredictionAccuracy = (Vector3.Distance(clientStateBuffer[j].pos, serverStateBuffer[0].pos));
  120.                         match = true;
  121.                         break;
  122.                     }
  123.                 }
  124.             }
  125.            
  126.             if(!match)
  127.             {
  128.                 //Debug.log("Not match");  
  129.             }
  130.             else if(m_PredictionAccuracy > m_PredictionThreshold) //if prediction is off, diverge current location by the amount of the offset
  131.             {
  132.                 if(Debug.isDebugBuild) Debug.Log("PredictionAccuracy sup to Predictionthreshold");
  133.                
  134.                 //Find how fat we travelled since the prediction failed
  135.                 Vector3 localMovement = clientStateBuffer[j].pos - clientStateBuffer[0].pos;
  136.                
  137.                 //"Erase" old value in the local buffer
  138.                 m_LocalStateCount = 1;
  139.                
  140.                 //New position which we need to converge to in the update loop
  141.                 m_NewPosition = serverStateBuffer[0].pos;
  142.                
  143.                 m_NewRotation = serverStateBuffer[0].rot;
  144.                
  145.                 //Trigger the new position convergence routine
  146.                 m_FixError = true;
  147.             }
  148.             else
  149.             {
  150.                 m_FixError = false;
  151.             }
  152.         }
  153.     }
  154.    
  155.     // Update is called once per frame
  156.     void Update ()
  157.     {  
  158.         if(m_FixError)
  159.         {
  160.             //transform.position = Vector3.Lerp(m_NewPosition, transform.position, difference.magnitude);
  161.             Vector3 predictPos = (m_NewPosition/2) + (clientStateBuffer[0].pos/2);
  162.             Vector3 difference = predictPos - transform.position;
  163.            
  164.            
  165.             transform.position = Vector3.Lerp(transform.position, predictPos, difference.magnitude);
  166.             transform.rotation = Quaternion.Slerp(transform.rotation, m_NewRotation, difference.magnitude);
  167.         }
  168.        
  169.        
  170.     }
  171.    
  172. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement