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): var interpolationBackTime = 0.1; private var m_BufferedState : Array = new State[20]; // where we store the State of our controller private var m_TimestampCount : int; // keeps track of what slots are used // Holds information about the controllers movements and last sent information from the network class State { var timeStamp : float; var pos : Vector3; var rot : Quaternion; } function OnSerializeNetworkView(stream : BitStream, info : NetworkMessageInfo) { if (stream.isWriting) { var pos = transform.position; var rot = transform.rotation; stream.Serialize(pos); stream.Serialize(rot); } else { pos = Vector3.zero; rot = Quaternion.identity; stream.Serialize(pos); stream.Serialize(rot); for (var i = m_BufferedState.length - 1; i >= 1; i --) { m_BufferedState[i] = m_BufferedState[i-1]; } var state = new State(); state.timeStamp = info.timestamp; state.pos = pos; state.rot = rot; m_BufferedState[0] = state; m_TimestampCount = Mathf.Min(m_TimestampCount + 1, m_BufferedState.length); for (i = 0; i < m_TimestampCount-1; i++) { if (m_BufferedState[i].timeStamp < m_BufferedState[i+1].timeStamp) { Debug.Log("State inconsistent"); } } } } function Update () { if (!networkView.isMine) { var currentTime = Network.time; var interpolationTime = currentTime - interpolationBackTime; if (m_BufferedState[0] != null m_BufferedState[0].timeStamp > interpolationTime) { for (var i = 0; i < m_TimestampCount; i++) { if (m_BufferedState[i].timeStamp <= interpolationTime || i == m_TimestampCount - 1) { // The state one slot newer (<100ms) than the best playback state var rhs : State = m_BufferedState[Mathf.Max(i-1, 0)]; // The best playback state (closest to 100 ms old (default time)) var lhs : State = m_BufferedState[i]; // Use the time between the two slots to determine if interpolation is necessary var length = rhs.timeStamp - lhs.timeStamp; var t : float = 0.0; if (length > 0.0001) { t = ((interpolationTime - lhs.timeStamp) / length); } // if t=0 => lhs is used directly transform.position = Vector3.Lerp(lhs.pos, rhs.pos, t); transform.rotation = Quaternion.Slerp(lhs.rot, rhs.rot, t); return; } } } else { if (m_BufferedState[0] != null) { var latest = m_BufferedState[0]; transform.position = latest.pos; transform.rotation = latest.rot; } } } } To use it, just drop the script onto your CharacterController, attach a NetworkView, and set the NetworkView to observe the script. Good luck...