Guest User

Untitled

a guest
Aug 21st, 2013
118
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.             //take care of data for interpolating remote objects movements
  49.             //Shift up the buffer
  50.             for(int i = serverStateBuffer.Length - 1; i >= 1; i--)
  51.             {
  52.                 serverStateBuffer[i] = serverStateBuffer[i - 1];   
  53.             }
  54.            
  55.             //Override the first element with the latest server info
  56.             serverStateBuffer[0] = new NetState((float)info.timestamp, pos, rot);
  57.            
  58.             /*int m_TimestampCount;
  59.             for(int i = 0; i < m_TimestampCount-1; i++)
  60.             {
  61.                 if(serverStateBuffer[i].timeStamp < serverStateBuffer[i + 1].timeStamp)
  62.                 {
  63.                     Debug.Log("State inconsistent");   
  64.                 }
  65.             }*/
  66.            
  67.         }
  68.        
  69.     }
  70.    
  71.     // Use this for initialization
  72.     void Start ()
  73.     {
  74.         StartCoroutine(StoreLocalMovement());
  75.     }
  76.    
  77.     IEnumerator StoreLocalMovement()
  78.     {
  79.         while(true)
  80.         {
  81.             yield return new WaitForSeconds(1/10);
  82.            
  83.             //shift buffer content
  84.             for(int i = clientStateBuffer.Length - 1; i >= 1; i--)
  85.             {
  86.                 clientStateBuffer[i] = clientStateBuffer[i - 1];   
  87.             }
  88.            
  89.             clientStateBuffer[0] = new NetState((float)uLink.Network.time, transform.position, transform.rotation);
  90.            
  91.             m_LocalStateCount = Mathf.Min(m_LocalStateCount + 1, clientStateBuffer.Length);
  92.            
  93.             //
  94.             //Check if the client side prediction has an error
  95.             //
  96.            
  97.             //Find the local buffered state which is closest to network state in time
  98.             int j = 0;
  99.             bool match = false;
  100.             for(j = 0; j < m_LocalStateCount - 1; j++)
  101.             {
  102.                 if(serverStateBuffer[0] != null)
  103.                 {
  104.                     if(serverStateBuffer[0].timeStamp <= clientStateBuffer[j].timeStamp && clientStateBuffer[j].timeStamp - serverStateBuffer[0].timeStamp <= m_TimeThreshold)
  105.                     {
  106.                         if(Debug.isDebugBuild)
  107.                         {
  108.                             Debug.Log("Comparing state " + j + "localtime: " + clientStateBuffer[j].timeStamp  + " networktime: " + serverStateBuffer[0].timeStamp);
  109.                             Debug.Log("Local: " + clientStateBuffer[j].pos + " Network: " + serverStateBuffer[0].pos);
  110.                         }
  111.                        
  112.                         //m_TimeAccuracy = Mathf.Abs(clientStateBuffer[j].timeStamp - serverStateBuffer[0].timeStamp);
  113.                         m_PredictionAccuracy = (Vector3.Distance(clientStateBuffer[j].pos, serverStateBuffer[0].pos));
  114.                         match = true;
  115.                         break;
  116.                     }
  117.                 }
  118.             }
  119.            
  120.             if(!match)
  121.             {
  122.                 //Debug.log("Not match");  
  123.             }
  124.             else if(m_PredictionAccuracy > m_PredictionThreshold) //if prediction is off, diverge current location by the amount of the offset
  125.             {
  126.                 if(Debug.isDebugBuild) Debug.Log("PredictionAccuracy sup to Predictionthreshold");
  127.                
  128.                 //Find how fat we travelled since the prediction failed
  129.                 Vector3 localMovement = clientStateBuffer[j].pos - clientStateBuffer[0].pos;
  130.                
  131.                 //"Erase" old value in the local buffer
  132.                 m_LocalStateCount = 1;
  133.                
  134.                 //New position which we need to converge to in the update loop
  135.                 m_NewPosition = serverStateBuffer[0].pos;
  136.                
  137.                 m_NewRotation = serverStateBuffer[0].rot;
  138.                
  139.                 //Trigger the new position convergence routine
  140.                 m_FixError = true;
  141.             }
  142.             else
  143.             {
  144.                 m_FixError = false;
  145.             }
  146.         }
  147.     }
  148.    
  149.     // Update is called once per frame
  150.     void Update ()
  151.     {  
  152.         if(m_FixError)
  153.         {
  154.             //transform.position = Vector3.Lerp(m_NewPosition, transform.position, difference.magnitude);
  155.             Vector3 predictPos = (m_NewPosition/2) + (clientStateBuffer[0].pos/2);
  156.             Vector3 difference = predictPos - transform.position;
  157.            
  158.            
  159.             transform.position = Vector3.Lerp(transform.position, predictPos, difference.magnitude);
  160.             transform.rotation = Quaternion.Slerp(transform.rotation, m_NewRotation, difference.magnitude);
  161.         }
  162.        
  163.        
  164.     }
  165.    
  166. }
RAW Paste Data