Пример #1
0
        // 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;
        }
Пример #2
0
        // 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 compressed)
                localPosition = reader.ReadVector3(),
                localRotation = Compression.DecompressQuaternion(reader.ReadUInt32()),
                localScale    = reader.ReadVector3(),
                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);

            // 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.transform.localPosition,
                    localRotation = targetComponent.transform.localRotation,
                    localScale    = 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.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.transform.localPosition, start.localPosition) < oldDistance + newDistance)
                {
                    start.localPosition = targetComponent.transform.localPosition;
                    start.localRotation = targetComponent.transform.localRotation;
                    start.localScale    = targetComponent.transform.localScale;
                }
            }

            // set new destination in any case. new data is best data.
            goal = temp;
        }
Пример #3
0
        // serialization is needed by OnSerialize and by manual sending from authority
        static void SerializeIntoWriter(NetworkWriter writer, Vector3 position, Quaternion rotation, Compression compressRotation, Vector3 scale)
        {
            // serialize position
            writer.WriteVector3(position);

            // serialize rotation
            // writing quaternion = 16 byte
            // writing euler angles = 12 byte
            // -> quaternion->euler->quaternion always works.
            // -> gimbal lock only occurs when adding.
            Vector3 euler = rotation.eulerAngles;

            if (compressRotation == Compression.None)
            {
                // write 3 floats = 12 byte
                writer.WriteSingle(euler.x);
                writer.WriteSingle(euler.y);
                writer.WriteSingle(euler.z);
            }
            else if (compressRotation == Compression.Much)
            {
                // write 3 byte. scaling [0,360] to [0,255]
                writer.WriteByte(FloatBytePacker.ScaleFloatToByte(euler.x, 0, 360, byte.MinValue, byte.MaxValue));
                writer.WriteByte(FloatBytePacker.ScaleFloatToByte(euler.y, 0, 360, byte.MinValue, byte.MaxValue));
                writer.WriteByte(FloatBytePacker.ScaleFloatToByte(euler.z, 0, 360, byte.MinValue, byte.MaxValue));
            }
            else if (compressRotation == Compression.Lots)
            {
                // write 2 byte, 5 bits for each float
                writer.WriteUInt16(FloatBytePacker.PackThreeFloatsIntoUShort(euler.x, euler.y, euler.z, 0, 360));
            }

            // serialize scale
            writer.WriteVector3(scale);
        }