示例#1
0
        void FixedUpdate()
        {
            if (!sendMessagesAllowed)
            {
                return;
            }

            CheckSendRate();

            if (!CheckAnimStateChanged(out int stateHash, out float normalizedTime))
            {
                return;
            }

            NetworkWriter writer = new NetworkWriter();

            WriteParameters(writer, false);

            SendAnimationMessage(stateHash, normalizedTime, writer.ToArray());
        }
示例#2
0
        public static byte[] PackMessage(int msgType, MessageBase msg)
        {
            NetworkWriter writer = NetworkWriterPool.GetWriter();

            try
            {
                // write message type
                writer.WriteInt16((short)msgType);

                // serialize message into writer
                msg.Serialize(writer);

                // return byte[]
                return(writer.ToArray());
            }
            finally
            {
                NetworkWriterPool.Recycle(writer);
            }
        }
示例#3
0
        protected void SendEventInternal(int eventHash, NetworkWriter writer, string eventName)
        {
            if (!NetworkServer.active)
            {
                if (LogFilter.logWarn)
                {
                    Debug.LogWarning("SendEvent no server?");
                }
                return;
            }

            // construct the message
            SyncEventMessage message = new SyncEventMessage();

            message.netId     = netId;
            message.eventHash = eventHash;
            message.payload   = writer.ToArray();

            NetworkServer.SendToReady(gameObject, (short)MsgType.SyncEvent, message);
        }
示例#4
0
        /* TODO use or remove
         * void GenerateDataError(byte error)
         * {
         *  NetworkError dataError = (NetworkError)error;
         *  if (LogFilter.logError) { Debug.LogError("UNet Client Data Error: " + dataError); }
         *  GenerateError(error);
         * }
         *
         * void GenerateDisconnectError(byte error)
         * {
         *  NetworkError disconnectError = (NetworkError)error;
         *  if (LogFilter.logError) { Debug.LogError("UNet Client Disconnect Error: " + disconnectError); }
         *  GenerateError(error);
         * }
         */

        void GenerateError(byte error)
        {
            NetworkMessageDelegate msgDelegate;

            if (m_MessageHandlers.TryGetValue((short)MsgType.Error, out msgDelegate))
            {
                ErrorMessage msg = new ErrorMessage();
                msg.errorCode = error;

                // write the message to a local buffer
                NetworkWriter writer = new NetworkWriter();
                msg.Serialize(writer);

                NetworkMessage netMsg = new NetworkMessage();
                netMsg.msgType = (short)MsgType.Error;
                netMsg.reader  = new NetworkReader(writer.ToArray());
                netMsg.conn    = m_Connection;
                msgDelegate(netMsg);
            }
        }
示例#5
0
        // pack message before sending
        public static byte[] Pack <T>(T message) where T : IMessageBase
        {
            NetworkWriter writer = NetworkWriterPool.GetWriter();

            try
            {
                // write message type
                int msgType = GetId <T>();
                writer.WriteUInt16((ushort)msgType);

                // serialize message into writer
                message.Serialize(writer);

                // return byte[]
                return(writer.ToArray());
            }
            finally
            {
                NetworkWriterPool.Recycle(writer);
            }
        }
示例#6
0
        protected void SendTargetRPCInternal(NetworkConnection conn, int rpcHash, NetworkWriter writer, string rpcName)
        {
            // This cannot use NetworkServer.active, as that is not specific to this object.
            if (!isServer)
            {
                if (LogFilter.logWarn)
                {
                    Debug.LogWarning("TargetRpc call on un-spawned object");
                }
                return;
            }

            // construct the message
            RpcMessage message = new RpcMessage();

            message.netId   = netId;
            message.rpcHash = rpcHash;
            message.payload = writer.ToArray();

            conn.Send((short)MsgType.Rpc, message);
        }
示例#7
0
        void FixedUpdate()
        {
            if (!sendMessagesAllowed)
            {
                return;
            }

            CheckSendRate();

            for (int i = 0; i < Animator.layerCount; i++)
            {
                if (!CheckAnimStateChanged(out int stateHash, out float normalizedTime, i))
                {
                    continue;
                }

                var writer = new NetworkWriter();
                WriteParameters(writer);

                SendAnimationMessage(stateHash, normalizedTime, i, writer.ToArray());
            }
        }
示例#8
0
        void SendTransform()
        {
            if (!HasMoved() || ClientScene.readyConnection == null)
            {
                return;
            }

            NetworkWriter writer = new NetworkWriter();

            SerializeModeTransform(writer);

            LocalChildTransformMessage message = new LocalChildTransformMessage();

            message.netId      = netId;
            message.childIndex = m_ChildIndex;
            message.payload    = writer.ToArray();

            m_PrevPosition = m_Target.localPosition;
            m_PrevRotation = m_Target.localRotation;

            ClientScene.readyConnection.Send((short)MsgType.LocalChildTransform, message);
        }
示例#9
0
        protected void SendTargetRPCInternal(NetworkConnection conn, Type invokeClass, string rpcName, NetworkWriter writer, int channelId)
        {
            // this was in Weaver before
            if (!NetworkServer.active)
            {
                Debug.LogError("TargetRPC Function " + rpcName + " called on client.");
                return;
            }
            // connection parameter is optional. assign if null.
            if (conn == null)
            {
                conn = connectionToClient;
            }
            // this was in Weaver before
            if (conn is ULocalConnectionToServer)
            {
                Debug.LogError("TargetRPC Function " + rpcName + " called on connection to server");
                return;
            }
            // This cannot use NetworkServer.active, as that is not specific to this object.
            if (!isServer)
            {
                Debug.LogWarning("TargetRpc " + rpcName + " called on un-spawned object: " + name);
                return;
            }

            // construct the message
            RpcMessage message = new RpcMessage
            {
                netId          = netId,
                componentIndex = ComponentIndex,
                functionHash   = (invokeClass + ":" + rpcName).GetStableHashCode(), // type+func so Inventory.RpcUse != Equipment.RpcUse
                payload        = writer.ToArray()
            };

            conn.Send(message, channelId);
        }
示例#10
0
        // use this to implicitly become ready
        // -> extraMessage can contain character selection, etc.
        public static bool AddPlayer(NetworkConnection readyConn, MessageBase extraMessage)
        {
            // ensure valid ready connection
            if (readyConn != null)
            {
                s_IsReady         = true;
                s_ReadyConnection = readyConn;
            }

            if (!s_IsReady)
            {
                Debug.LogError("Must call AddPlayer() with a connection the first time to become ready.");
                return(false);
            }

            if (s_ReadyConnection.playerController != null)
            {
                Debug.LogError("ClientScene::AddPlayer: a PlayerController was already added. Did you call AddPlayer twice?");
                return(false);
            }

            if (LogFilter.Debug)
            {
                Debug.Log("ClientScene::AddPlayer() called with connection [" + s_ReadyConnection + "]");
            }

            AddPlayerMessage msg = new AddPlayerMessage();

            if (extraMessage != null)
            {
                NetworkWriter writer = new NetworkWriter();
                extraMessage.Serialize(writer);
                msg.value = writer.ToArray();
            }
            s_ReadyConnection.Send((short)MsgType.AddPlayer, msg);
            return(true);
        }
        void Update()
        {
            // if server then always sync to others.
            if (isServer)
            {
                // just use OnSerialize via SetDirtyBit only sync when position
                // changed. set dirty bits 0 or 1
                SetDirtyBit(HasEitherMovedRotatedScaled() ? 1UL : 0UL);
            }

            // no 'else if' since host mode would be both
            if (isClient)
            {
                // send to server if we have local authority (and aren't the server)
                // -> only if connectionToServer has been initialized yet too
                if (!isServer && isClientWithAuthority)
                {
                    // check only each 'syncInterval'
                    if (Time.time - lastClientSendTime >= syncInterval)
                    {
                        if (HasEitherMovedRotatedScaled())
                        {
                            // serialize
                            // local position/rotation for VR support
                            NetworkWriter writer = NetworkWriterPool.GetWriter();
                            SerializeIntoWriter(writer, targetComponent.transform.localPosition, targetComponent.transform.localRotation, compressRotation, targetComponent.transform.localScale);

                            // send to server
                            CmdClientToServerSync(writer.ToArray());
                            NetworkWriterPool.Recycle(writer);
                        }
                        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)
                {
                    // received one yet? (initialized?)
                    if (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.transform.localPosition),
                                                       InterpolateRotation(start, goal, targetComponent.transform.localRotation),
                                                       InterpolateScale(start, goal, targetComponent.transform.localScale));
                        }
                    }
                }
            }
        }
示例#12
0
        // use this to implicitly become ready
        public static bool AddPlayer(NetworkConnection readyConn, short playerControllerId, MessageBase extraMessage)
        {
            if (playerControllerId < 0)
            {
                if (LogFilter.logError)
                {
                    Debug.LogError("ClientScene::AddPlayer: playerControllerId of " + playerControllerId + " is negative");
                }
                return(false);
            }
            if (playerControllerId > PlayerController.MaxPlayersPerClient)
            {
                if (LogFilter.logError)
                {
                    Debug.LogError("ClientScene::AddPlayer: playerControllerId of " + playerControllerId + " is too high, max is " + PlayerController.MaxPlayersPerClient);
                }
                return(false);
            }
            if (playerControllerId > PlayerController.MaxPlayersPerClient / 2)
            {
                if (LogFilter.logWarn)
                {
                    Debug.LogWarning("ClientScene::AddPlayer: playerControllerId of " + playerControllerId + " is unusually high");
                }
            }

            // fill out local players array
            while (playerControllerId >= s_LocalPlayers.Count)
            {
                s_LocalPlayers.Add(new PlayerController());
            }

            // ensure valid ready connection
            if (readyConn != null)
            {
                s_IsReady         = true;
                s_ReadyConnection = readyConn;
            }

            if (!s_IsReady)
            {
                if (LogFilter.logError)
                {
                    Debug.LogError("Must call AddPlayer() with a connection the first time to become ready.");
                }
                return(false);
            }

            PlayerController existingPlayerController;

            if (s_ReadyConnection.GetPlayerController(playerControllerId, out existingPlayerController))
            {
                if (existingPlayerController.IsValid && existingPlayerController.gameObject != null)
                {
                    if (LogFilter.logError)
                    {
                        Debug.LogError("ClientScene::AddPlayer: playerControllerId of " + playerControllerId + " already in use.");
                    }
                    return(false);
                }
            }

            if (LogFilter.logDebug)
            {
                Debug.Log("ClientScene::AddPlayer() for ID " + playerControllerId + " called with connection [" + s_ReadyConnection + "]");
            }

            var msg = new AddPlayerMessage();

            msg.playerControllerId = playerControllerId;
            if (extraMessage != null)
            {
                var writer = new NetworkWriter();
                extraMessage.Serialize(writer);
                msg.msgData = writer.ToArray();
            }
            s_ReadyConnection.Send((short)MsgType.AddPlayer, msg);
            return(true);
        }
示例#13
0
        internal static void SendSpawnMessage(NetworkIdentity uv, NetworkConnection conn)
        {
            if (uv.serverOnly)
            {
                return;
            }

            if (LogFilter.Debug)
            {
                Debug.Log("Server SendSpawnMessage: name=" + uv.name + " sceneId=" + uv.sceneId + " netid=" + uv.netId);
            }                                                                                                                                 // for easier debugging

            // 'uv' is a prefab that should be spawned
            if (uv.sceneId == 0)
            {
                SpawnPrefabMessage msg = new SpawnPrefabMessage();
                msg.netId    = uv.netId;
                msg.assetId  = uv.assetId;
                msg.position = uv.transform.position;
                msg.rotation = uv.transform.rotation;

                // serialize all components with initialState = true
                NetworkWriter writer = new NetworkWriter();
                uv.OnSerializeAllSafely(writer, true);
                msg.payload = writer.ToArray();

                // conn is != null when spawning it for a client
                if (conn != null)
                {
                    conn.Send((short)MsgType.SpawnPrefab, msg);
                }
                // conn is == null when spawning it for the local player
                else
                {
                    SendToReady(uv.gameObject, (short)MsgType.SpawnPrefab, msg);
                }
            }
            // 'uv' is a scene object that should be spawned again
            else
            {
                SpawnSceneObjectMessage msg = new SpawnSceneObjectMessage();
                msg.netId    = uv.netId;
                msg.sceneId  = uv.sceneId;
                msg.position = uv.transform.position;

                // include synch data
                NetworkWriter writer = new NetworkWriter();
                uv.OnSerializeAllSafely(writer, true);
                msg.payload = writer.ToArray();

                // conn is != null when spawning it for a client
                if (conn != null)
                {
                    conn.Send((short)MsgType.SpawnSceneObject, msg);
                }
                // conn is == null when spawning it for the local player
                else
                {
                    SendToReady(uv.gameObject, (short)MsgType.SpawnSceneObject, msg);
                }
            }
        }