zoukankan      html  css  js  c++  java
  • NETWORK_同步位置信息

    using UnityEngine;
    using System.Collections;

    public class NetworkInterpolatedTransform : MonoBehaviour {
     
     public double interpolationBackTime = 0.1;
     
     internal struct  State
     {
      internal double timestamp;
      internal Vector3 pos;
      internal Quaternion rot;
     }

     // We store twenty states with "playback" information
     State[] m_BufferedState = new State[20];
     // Keep track of what slots are used
     int m_TimestampCount;
     
     void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
     {
      // Always send transform (depending on reliability of the network view)
      if (stream.isWriting)
      {
       Vector3 pos = transform.localPosition;
       Quaternion rot = transform.localRotation;
       stream.Serialize(ref pos);
       stream.Serialize(ref rot);
      }
      // When receiving, buffer the information
      else
      {
       // Receive latest state information
       Vector3 pos = Vector3.zero;
       Quaternion rot = Quaternion.identity;
       stream.Serialize(ref pos);
       stream.Serialize(ref rot);
       
       // Shift buffer contents, oldest data erased, 18 becomes 19, ... , 0 becomes 1
       for (int i=m_BufferedState.Length-1;i>=1;i--)
       {
        m_BufferedState[i] = m_BufferedState[i-1];
       }
       
       // Save currect received state as 0 in the buffer, safe to overwrite after shifting
       State state;
       state.timestamp = info.timestamp;
       state.pos = pos;
       state.rot = rot;
       m_BufferedState[0] = state;
       
       // Increment state count but never exceed buffer size
       m_TimestampCount = Mathf.Min(m_TimestampCount + 1, m_BufferedState.Length);

       // Check integrity, lowest numbered state in the buffer is newest and so on
       for (int i=0;i<m_TimestampCount-1;i++)
       {
        if (m_BufferedState[i].timestamp < m_BufferedState[i+1].timestamp)
         Debug.Log("State inconsistent");
       }
       
       //Debug.Log("stamp: " + info.timestamp + "my time: " + Network.time + "delta: " + (Network.time - info.timestamp));
      }
     }
     
     // This only runs where the component is enabled, which is only on remote peers (server/clients)
     void Update () {
      double currentTime = Network.time;
      double interpolationTime = currentTime - interpolationBackTime;
      // We have a window of interpolationBackTime where we basically play
      // By having interpolationBackTime the average ping, you will usually use interpolation.
      // And only if no more data arrives we will use extrapolation
      
      // Use interpolation
      // Check if latest state exceeds interpolation time, if this is the case then
      // it is too old and extrapolation should be used
      if (m_BufferedState[0].timestamp > interpolationTime)
      {
       for (int i=0;i<m_TimestampCount;i++)
       {
        // Find the state which matches the interpolation time (time+0.1) or use last state
        if (m_BufferedState[i].timestamp <= interpolationTime || i == m_TimestampCount-1)
        {
         // The state one slot newer (<100ms) than the best playback state
         State rhs = m_BufferedState[Mathf.Max(i-1, 0)];
         // The best playback state (closest to 100 ms old (default time))
         State lhs = m_BufferedState[i];
         
         // Use the time between the two slots to determine if interpolation is necessary
         double length = rhs.timestamp - lhs.timestamp;
         float t = 0.0F;
         // As the time difference gets closer to 100 ms t gets closer to 1 in
         // which case rhs is only used
         if (length > 0.0001)
          t = (float)((interpolationTime - lhs.timestamp) / length);
         
         // if t=0 => lhs is used directly
         transform.localPosition = Vector3.Lerp(lhs.pos, rhs.pos, t);
         transform.localRotation = Quaternion.Slerp(lhs.rot, rhs.rot, t);
         return;
        }
       }
      }
      // Use extrapolation. Here we do something really simple and just repeat the last
      // received state. You can do clever stuff with predicting what should happen.
      else
      {
       State latest = m_BufferedState[0];
       
       transform.localPosition = latest.pos;
       transform.localRotation = latest.rot;
      }
     }
    }

  • 相关阅读:
    《软件工程》第十六周学习进度
    个人总结
    构建之法阅读笔记06
    《软件工程》第十五周学习进度
    构建之法阅读笔记05
    《软件工程》第十四周学习进度
    买书问题
    第二阶段团队项目冲刺第十天
    第二阶段团队项目冲刺第九天
    第二阶段团队项目冲刺第八天
  • 原文地址:https://www.cnblogs.com/softimagewht/p/2164603.html
Copyright © 2011-2022 走看看