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 interpolationTime) { for (int i=0;i 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; } } }