void OnMessageNetworkObjectList(byte[] data, ulong steamID) { MessageNetworkObjectList messageNetworkObjectList = MessageNetworkObjectList.FromBytes(data, 0); foreach (byte[] b in messageNetworkObjectList.messages) { UpdateNetworkObject(MessageNetworkObject.FromBytes(b, 0)); } }
public void RegisterAndSendMessageNetworkObject(NetworkObject networkObject) { if (allClientsInitialized) { // Make sure that objects are spawned on the server (with UDP it could happen that they don't spawn) MessageNetworkObject message = new MessageNetworkObject(networkObject); NetworkManager.Instance.SendToAllClients(message.ToBytes(), NetworkMessageType.NetworkObject, SendType.Reliable); } networkObjects.Add(networkObject.networkID, networkObject); }
public void UpdateTransformFromMessageNetworkObject(MessageNetworkObject messageNetworkObject) { if (!onServer) { if (interpolateOnClient) { interpolationMessages.AddLast(messageNetworkObject); } else { // Directly update the transform transform.localPosition = messageNetworkObject.localPosition; transform.localRotation = messageNetworkObject.localRotation; transform.localScale = messageNetworkObject.localScale; } } }
private void SendAllNetworkObjects(bool onlySendChangedTransforms, SendType sendType) { // Save all network object messages that need to be sended into one pool // Sort the pool by the depth of the transform in the hierarchy // This makes sure that parents are instantiated before their children List <KeyValuePair <int, NetworkObject> > networkObjectsToSend = new List <KeyValuePair <int, NetworkObject> >(); foreach (NetworkObject networkObject in networkObjects.Values) { if (!onlySendChangedTransforms || networkObject.HasChanged()) { KeyValuePair <int, NetworkObject> networkObjectToAdd = new KeyValuePair <int, NetworkObject>(GetHierarchyDepthOfTransform(networkObject.transform, 0), networkObject); networkObjectsToSend.Add(networkObjectToAdd); } } // Sort by the depth of the transform networkObjectsToSend.Sort ( delegate(KeyValuePair <int, NetworkObject> a, KeyValuePair <int, NetworkObject> b) { return(a.Key - b.Key); } ); // Standard is UDP packet size, 1200 bytes int maximumTransmissionLength = 1200; if (sendType == SendType.Reliable) { // TCP packet, up to 1MB maximumTransmissionLength = 1000000; } // Create and send network object list messages until the pool is empty while (networkObjectsToSend.Count > 0) { // Make sure that the message is small enough to fit into the UDP packet (1200 bytes) MessageNetworkObjectList messageNetworkObjectList = new MessageNetworkObjectList(); while (true) { if (networkObjectsToSend.Count > 0) { // Add next message MessageNetworkObject message = new MessageNetworkObject(networkObjectsToSend[0].Value); messageNetworkObjectList.messages.AddLast(message.ToBytes()); // Check if length is still small enough if (messageNetworkObjectList.GetLength() <= maximumTransmissionLength) { // Small enough, keep message and remove from objects to send networkObjectsToSend.RemoveAt(0); } else { // Too big, remove message and create a new list to send the rest messageNetworkObjectList.messages.RemoveLast(); break; } } else { break; } } // Send the message to all clients NetworkManager.Instance.SendToAllClients(messageNetworkObjectList.ToBytes(), NetworkMessageType.NetworkObjectList, sendType); } }
void UpdateNetworkObject(MessageNetworkObject messageNetworkObject) { // Create a new object if it doesn't exist yet if (!objectsFromServer.ContainsKey(messageNetworkObject.instanceID)) { // Make sure that the parent exists already if it has one if (!messageNetworkObject.hasParent || objectsFromServer.ContainsKey(messageNetworkObject.parentInstanceID)) { // Check if the object is a prefab or a child of a prefab (resourceID < 0) if (messageNetworkObject.resourceID > 0) { // Switch active scene so that instantiate creates the object as part of the client scene Scene previouslyActiveScene = SceneManager.GetActiveScene(); SceneManager.SetActiveScene(gameObject.scene); // Instantiate the object NetworkObject tmp = Instantiate(networkObjectPrefabs[messageNetworkObject.resourceID]).GetComponent <NetworkObject>(); objectsFromServer[messageNetworkObject.instanceID] = tmp; // Switch back to the previously active scene SceneManager.SetActiveScene(previouslyActiveScene); // Set attributes, also update transform after spawn tmp.onServer = false; tmp.networkID = messageNetworkObject.instanceID; tmp.transform.localPosition = messageNetworkObject.localPosition; tmp.transform.localRotation = messageNetworkObject.localRotation; tmp.transform.localScale = messageNetworkObject.localScale; } else if (messageNetworkObject.resourceID < 0) { // Then only the transform should be synchronized and no objects should be spawned // The root resource has an array of all children where the index is the childId // Client children find themselves with root.children[-resourceID - 1] // Find root, then child and assign to objectsFromServer NetworkObject root = objectsFromServer[messageNetworkObject.rootInstanceID]; NetworkObject child = root.children[-messageNetworkObject.resourceID - 1]; child.networkID = messageNetworkObject.instanceID; child.onServer = false; // Add to the dictionairy to make sure that this object is updated with messages objectsFromServer.Add(child.networkID, child); } } } if (objectsFromServer.ContainsKey(messageNetworkObject.instanceID)) { NetworkObject networkObject = objectsFromServer[messageNetworkObject.instanceID]; if (networkObject.lastUpdate <= messageNetworkObject.time) { // Update values only if the UDP packet values are newer networkObject.name = "[" + messageNetworkObject.instanceID + "]\t" + messageNetworkObject.name; networkObject.lastUpdate = messageNetworkObject.time; // Update the transform networkObject.UpdateTransformFromMessageNetworkObject(messageNetworkObject); // Update parent if possible if (messageNetworkObject.hasParent) { if (objectsFromServer.ContainsKey(messageNetworkObject.parentInstanceID)) { networkObject.transform.SetParent(objectsFromServer[messageNetworkObject.parentInstanceID].transform, false); } } else { networkObject.transform.SetParent(null); } } } else { // This can e.g. happen when loading a different scene and some messages from the previous scene arrive Debug.LogWarning(nameof(GameClient) + " does not have a " + nameof(NetworkObject) + " with the instance id " + messageNetworkObject.instanceID + "!"); } }
void OnMessageNetworkObject(byte[] data, ulong steamID) { UpdateNetworkObject(MessageNetworkObject.FromBytes(data, 0)); }