示例#1
0
        /// <summary>
        /// This sends a network message to the connection.
        /// </summary>
        /// <typeparam name="T">The message type</typeparam>
        /// <param name="msg">The message to send.</param>
        /// <param name="channelId">The transport layer channel to send on.</param>
        /// <returns></returns>
        public void Send <T>(T message, INotifyCallBack token)
        {
            if (isDisconnected)
            {
                return;
            }

            using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
            {
                MessagePacker.Pack(message, writer);

                var segment = writer.ToArraySegment();
                NetworkDiagnostics.OnSend(message, segment.Count, 1);
                connection.SendNotify(segment, token);
            }
        }
示例#2
0
        /// <summary>
        /// This sends a network message to the connection.
        /// </summary>
        /// <typeparam name="T">The message type</typeparam>
        /// <param name="msg">The message to send.</param>
        /// <param name="channelId">The transport layer channel to send on.</param>
        /// <returns></returns>
        public void Send <T>(T message, int channelId = Channel.Reliable)
        {
            if (isDisconnected)
            {
                return;
            }

            using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
            {
                MessagePacker.Pack(message, writer);

                var segment = writer.ToArraySegment();
                NetworkDiagnostics.OnSend(message, segment.Count, 1);
                Send(segment, channelId);
            }
        }
示例#3
0
        void CheckSendRate()
        {
            float now = Time.time;

            if (SendMessagesAllowed && syncInterval >= 0 && now > nextSendTime)
            {
                nextSendTime = now + syncInterval;

                using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
                {
                    if (WriteParameters(writer))
                    {
                        SendAnimationParametersMessage(writer.ToArray());
                    }
                }
            }
        }
示例#4
0
        void UpdateClient()
        {
            // send to server if we have local authority (and aren't the server)
            // -> only if connectionToServer has been initialized yet too
            // check only each 'syncInterval'
            if (!IsServer && IsClientWithAuthority && Time.time - lastClientSendTime >= syncInterval)
            {
                if (HasEitherMovedRotatedScaled())
                {
                    // serialize
                    // local position/rotation for VR support
                    using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
                    {
                        SerializeIntoWriter(writer, TargetComponent.localPosition, TargetComponent.localRotation, TargetComponent.localScale);

                        // send to server
                        CmdClientToServerSync(writer.ToArray());
                    }
                }
                lastClientSendTime = Time.time;
            }

            // apply interpolation on client for all players
            // unless this client has authority over the object. could be
            // himself or another object that he was assigned authority over
            if (!IsClientWithAuthority && goal != null)
            {
                // teleport or interpolate
                if (NeedsTeleport())
                {
                    // local position/rotation for VR support
                    ApplyPositionRotationScale(goal.LocalPosition, goal.LocalRotation, goal.LocalScale);

                    // reset data points so we don't keep interpolating
                    start = null;
                    goal  = null;
                }
                else
                {
                    // local position/rotation for VR support
                    ApplyPositionRotationScale(InterpolatePosition(start, goal, TargetComponent.localPosition),
                                               InterpolateRotation(start, goal, TargetComponent.localRotation),
                                               InterpolateScale(start, goal, TargetComponent.localScale));
                }
            }
        }
示例#5
0
        /// <summary>
        /// Sends a message to many connections
        /// <para>
        /// Same as <see cref="SendToMany{T}(IEnumerable{INetworkPlayer}, T, int)"/> but uses for loop to avoid allocations
        /// </para>
        /// </summary>
        /// <remarks>
        /// Using list in foreach loop causes Unity's mono version to box the struct which causes allocations, <see href="https://docs.unity3d.com/2019.4/Documentation/Manual/BestPracticeUnderstandingPerformanceInUnity4-1.html">Understanding the managed heap</see>
        /// </remarks>
        public static void SendToMany <T>(IReadOnlyList <INetworkPlayer> players, T msg, int channelId = Channel.Reliable)
        {
            using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
            {
                // pack message into byte[] once
                MessagePacker.Pack(msg, writer);
                var segment = writer.ToArraySegment();
                int count   = players.Count;

                for (int i = 0; i < count; i++)
                {
                    players[i].Send(segment, channelId);
                }

                NetworkDiagnostics.OnSend(msg, segment.Count, count);
            }
        }
示例#6
0
        /// <summary>
        /// Sends a message to many connections
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="players"></param>
        /// <param name="msg"></param>
        /// <param name="channelId"></param>
        public static void SendToMany <T>(IEnumerable <INetworkPlayer> players, T msg, int channelId = Channel.Reliable)
        {
            using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
            {
                // pack message into byte[] once
                MessagePacker.Pack(msg, writer);
                var segment = writer.ToArraySegment();
                int count   = 0;

                foreach (INetworkPlayer player in players)
                {
                    player.Send(segment, channelId);
                    count++;
                }

                NetworkDiagnostics.OnSend(msg, segment.Count, count);
            }
        }
示例#7
0
        internal void SendSpawnMessage(NetworkIdentity identity, INetworkPlayer player)
        {
            if (logger.LogEnabled())
            {
                logger.Log($"Server SendSpawnMessage: name={identity.name} sceneId={identity.SceneId:X} netId={identity.NetId}");
            }

            // one writer for owner, one for observers
            using (PooledNetworkWriter ownerWriter = NetworkWriterPool.GetWriter(), observersWriter = NetworkWriterPool.GetWriter())
            {
                var isOwner = identity.Owner == player;

                var payload = CreateSpawnMessagePayload(isOwner, identity, ownerWriter, observersWriter);

                var prefabHash = identity.IsPrefab ? identity.PrefabHash : default(int?);
                var sceneId    = identity.IsSceneObject ? identity.SceneId : default(ulong?);
                var msg        = new SpawnMessage
                {
                    netId         = identity.NetId,
                    isLocalPlayer = player.Identity == identity,
                    isOwner       = isOwner,
                    sceneId       = sceneId,
                    prefabHash    = prefabHash,
                    payload       = payload,
                };

                // values in msg are nullable, so by default they are null
                // only set those values if the identity's settings say to send them
                if (identity.SpawnSettings.SendPosition)
                {
                    msg.position = identity.transform.localPosition;
                }
                if (identity.SpawnSettings.SendRotation)
                {
                    msg.rotation = identity.transform.localRotation;
                }
                if (identity.SpawnSettings.SendScale)
                {
                    msg.scale = identity.transform.localScale;
                }

                player.Send(msg);
            }
        }
示例#8
0
        public static void Send <T>(IEnumerable <INetworkConnection> connections, T msg, int channelId = Channel.Reliable)
        {
            using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
            {
                // pack message into byte[] once
                MessagePacker.Pack(msg, writer);
                var segment = writer.ToArraySegment();
                int count   = 0;

                foreach (INetworkConnection conn in connections)
                {
                    // send to all connections, but don't wait for them
                    conn.Send(segment, channelId);
                    count++;
                }

                NetworkDiagnostics.OnSend(msg, channelId, segment.Count, count);
            }
        }
示例#9
0
 static ArraySegment <byte> CreateSpawnMessagePayload(bool isOwner, NetworkIdentity identity, PooledNetworkWriter ownerWriter, PooledNetworkWriter observersWriter)
 {
     // Only call OnSerializeAllSafely if there are NetworkBehaviours
     if (identity.NetworkBehaviours.Length == 0)
     {
         return(default);