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()); }
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); } }
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); }
/* 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); } }
// 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); } }
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); }
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()); } }
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); }
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); }
// 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)); } } } } }
// 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); }
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); } } }