Search Unity

Network transform prediction

Discussion in 'Multiplayer' started by blue2fox, Apr 15, 2009.

  1. blue2fox

    blue2fox

    Joined:
    Jun 8, 2008
    Posts:
    91
    Hi... here's a translated version of the Network Tutorials "NetworkInterpolatedTransform.cs" into JavaScript. It helps with the network transform predictions. I couldn't get the C# version of the script to work with my CharacterControllers, and perhaps someone else might need this script.


    Code (csharp):
    1.  
    2. var interpolationBackTime = 0.1;
    3.  
    4. private var m_BufferedState : Array = new State[20]; // where we store the State of our controller
    5. private var m_TimestampCount : int; // keeps track of what slots are used
    6.  
    7.  
    8. // Holds information about the controllers movements and last sent information from the network
    9. class State
    10. {
    11.     var timeStamp : float;
    12.     var pos : Vector3;
    13.     var rot : Quaternion;
    14. }
    15.  
    16. function OnSerializeNetworkView(stream : BitStream, info : NetworkMessageInfo)
    17. {
    18.     if (stream.isWriting)
    19.     {
    20.         var pos = transform.position;
    21.         var rot = transform.rotation;
    22.        
    23.         stream.Serialize(pos);
    24.         stream.Serialize(rot);
    25.     }
    26.     else
    27.     {
    28.         pos = Vector3.zero;
    29.         rot = Quaternion.identity;
    30.         stream.Serialize(pos);
    31.         stream.Serialize(rot);
    32.        
    33.        
    34.         for (var i = m_BufferedState.length - 1; i >= 1; i --)
    35.         {
    36.             m_BufferedState[i] = m_BufferedState[i-1];
    37.         }
    38.        
    39.         var state = new State();
    40.         state.timeStamp = info.timestamp;
    41.         state.pos = pos;
    42.         state.rot = rot;
    43.         m_BufferedState[0] = state;
    44.        
    45.         m_TimestampCount = Mathf.Min(m_TimestampCount + 1, m_BufferedState.length);
    46.        
    47.         for (i = 0; i < m_TimestampCount-1; i++)
    48.         {
    49.             if (m_BufferedState[i].timeStamp < m_BufferedState[i+1].timeStamp)
    50.             {
    51.                 Debug.Log("State inconsistent");
    52.             }
    53.         }
    54.     }
    55. }
    56.  
    57. function Update ()
    58. {
    59.     if (!networkView.isMine)
    60.     {      
    61.         var currentTime = Network.time;
    62.         var interpolationTime = currentTime - interpolationBackTime;
    63.    
    64.         if (m_BufferedState[0] != null  m_BufferedState[0].timeStamp > interpolationTime)
    65.         {
    66.             for (var i = 0; i < m_TimestampCount; i++)
    67.             {
    68.                 if (m_BufferedState[i].timeStamp <= interpolationTime || i == m_TimestampCount - 1)
    69.                 {
    70.                     // The state one slot newer (<100ms) than the best playback state
    71.                     var rhs : State = m_BufferedState[Mathf.Max(i-1, 0)];
    72.                     // The best playback state (closest to 100 ms old (default time))
    73.                     var lhs : State = m_BufferedState[i];
    74.                    
    75.                     // Use the time between the two slots to determine if interpolation is necessary
    76.                     var length = rhs.timeStamp - lhs.timeStamp;
    77.                     var t : float = 0.0;
    78.                    
    79.                     if (length > 0.0001)
    80.                     {
    81.                         t = ((interpolationTime - lhs.timeStamp) / length);
    82.                     }
    83.                    
    84.                     // if t=0 => lhs is used directly
    85.                     transform.position = Vector3.Lerp(lhs.pos, rhs.pos, t);
    86.                     transform.rotation = Quaternion.Slerp(lhs.rot, rhs.rot, t);
    87.                     return;
    88.                    
    89.                 }
    90.             }
    91.         }
    92.         else
    93.         {
    94.             if (m_BufferedState[0] != null)
    95.             {
    96.                 var latest = m_BufferedState[0];
    97.                 transform.position = latest.pos;
    98.                 transform.rotation = latest.rot;
    99.             }
    100.         }
    101.     }
    102. }
    103.  
    104.  
    To use it, just drop the script onto your CharacterController, attach a NetworkView, and set the NetworkView to observe the script. Good luck...
     
  2. DrHotbunz

    DrHotbunz

    Joined:
    Feb 14, 2009
    Posts:
    315
    I owe you a thank you. Since I am using this.

    Thanks for sharing.