public override void OnDeserialize(NetworkReader reader, bool initialState) { // sync target component's position on spawn. // fixes https://github.com/vis2k/Mirror/pull/3051/ // (Spawn message wouldn't sync NTChild positions either) if (initialState) { if (syncPosition) { targetComponent.localPosition = reader.ReadVector3(); } if (syncRotation) { targetComponent.localRotation = reader.ReadQuaternion(); } if (syncScale) { targetComponent.localScale = reader.ReadVector3(); } } }
// serialization is needed by OnSerialize and by manual sending from authority void DeserializeFromReader(NetworkReader reader) { // put it into a data point immediately DataPoint temp = new DataPoint { // deserialize position thePosition = reader.ReadVector3() }; // deserialize rotation & scale temp.theRotation = reader.ReadQuaternion(); temp.theScale = reader.ReadVector3(); temp.timeStamp = Time.time; // movement speed: based on how far it moved since last time // has to be calculated before 'start' is overwritten temp.movementSpeed = EstimateMovementSpeed(goal, temp, targetComponent.transform, syncInterval, useGlobalPosition); // reassign start wisely // -> first ever data point? then make something up for previous one // so that we can start interpolation without waiting for next. if (start == null) { if (useGlobalPosition) { start = new DataPoint { timeStamp = Time.time - syncInterval, // local position/rotation for VR support thePosition = targetComponent.transform.position, theRotation = targetComponent.transform.rotation, theScale = targetComponent.transform.localScale, movementSpeed = temp.movementSpeed }; } else { start = new DataPoint { timeStamp = Time.time - syncInterval, // local position/rotation for VR support thePosition = targetComponent.transform.localPosition, theRotation = targetComponent.transform.localRotation, theScale = targetComponent.transform.localScale, movementSpeed = temp.movementSpeed }; } } // -> second or nth data point? then update previous, but: // we start at where ever we are right now, so that it's // perfectly smooth and we don't jump anywhere // // example if we are at 'x': // // A--x->B // // and then receive a new point C: // // A--x--B // | // | // C // // then we don't want to just jump to B and start interpolation: // // x // | // | // C // // we stay at 'x' and interpolate from there to C: // // x..B // \ . // \. // C // else { float oldDistance = Vector3.Distance(start.thePosition, goal.thePosition); float newDistance = Vector3.Distance(goal.thePosition, temp.thePosition); start = goal; // teleport / lag / obstacle detection: only continue at current // position if we aren't too far away // // local position/rotation for VR support if (useGlobalPosition) { if (Vector3.Distance(targetComponent.transform.position, start.thePosition) < oldDistance + newDistance) { start.thePosition = targetComponent.transform.position; start.theRotation = targetComponent.transform.rotation; start.theScale = targetComponent.transform.localScale; } } else { if (Vector3.Distance(targetComponent.transform.localPosition, start.thePosition) < oldDistance + newDistance) { start.thePosition = targetComponent.transform.localPosition; start.theRotation = targetComponent.transform.localRotation; start.theScale = targetComponent.transform.localScale; } } } // set new destination in any case. new data is best data. goal = temp; }
// serialization is needed by OnSerialize and by manual sending from authority void DeserializeFromReader(NetworkReader reader) { // put it into a data point immediately DataPoint temp = new DataPoint { // deserialize position, rotation, scale // (rotation is optionally compressed) localPosition = reader.ReadVector3(), localRotation = compressRotation ? Compression.DecompressQuaternion(reader.ReadUInt()) : reader.ReadQuaternion(), // use current target scale, so we can check boolean and reader later, to see if the data is actually sent. localScale = targetComponent.localScale, timeStamp = Time.time }; if (syncScale) { // Reader length is checked here, 12 is used as thats the current Vector3 (3 floats) amount. // In rare cases people may do mis-matched builds, log useful warning message, and then do not process missing scale data. if (reader.Length >= 12) { temp.localScale = reader.ReadVector3(); } else { Debug.LogWarning("Reader length does not contain enough data for a scale, please check that both server and client builds syncScale booleans match.", this); } } // movement speed: based on how far it moved since last time // has to be calculated before 'start' is overwritten temp.movementSpeed = EstimateMovementSpeed(goal, temp, targetComponent, syncInterval); // reassign start wisely // -> first ever data point? then make something up for previous one // so that we can start interpolation without waiting for next. if (start == null) { start = new DataPoint { timeStamp = Time.time - syncInterval, // local position/rotation for VR support localPosition = targetComponent.localPosition, localRotation = targetComponent.localRotation, localScale = targetComponent.localScale, movementSpeed = temp.movementSpeed }; } // -> second or nth data point? then update previous, but: // we start at where ever we are right now, so that it's // perfectly smooth and we don't jump anywhere // // example if we are at 'x': // // A--x->B // // and then receive a new point C: // // A--x--B // | // | // C // // then we don't want to just jump to B and start interpolation: // // x // | // | // C // // we stay at 'x' and interpolate from there to C: // // x..B // \ . // \. // C // else { float oldDistance = Vector3.Distance(start.localPosition, goal.localPosition); float newDistance = Vector3.Distance(goal.localPosition, temp.localPosition); start = goal; // teleport / lag / obstacle detection: only continue at current // position if we aren't too far away // // local position/rotation for VR support if (Vector3.Distance(targetComponent.localPosition, start.localPosition) < oldDistance + newDistance) { start.localPosition = targetComponent.localPosition; start.localRotation = targetComponent.localRotation; start.localScale = targetComponent.localScale; } } // set new destination in any case. new data is best data. goal = temp; }