// invoked by unity runtime immediately after the regular "Update()" function. internal void UNetUpdate() { // check if any behaviours are ready to send uint dirtyChannelBits = 0; for (int i = 0; i < m_NetworkBehaviours.Length; i++) { NetworkBehaviour comp = m_NetworkBehaviours[i]; int channelId = comp.GetDirtyChannel(); if (channelId != -1) { dirtyChannelBits |= (uint)(1 << channelId); } } if (dirtyChannelBits == 0) { return; } for (int channelId = 0; channelId < NetworkServer.numChannels; channelId++) { if ((dirtyChannelBits & (uint)(1 << channelId)) != 0) { s_UpdateWriter.StartMessage(MsgType.UpdateVars); s_UpdateWriter.Write(netId); bool wroteData = false; int oldPos; for (int i = 0; i < m_NetworkBehaviours.Length; i++) { oldPos = s_UpdateWriter.Position; NetworkBehaviour comp = m_NetworkBehaviours[i]; if (comp.GetDirtyChannel() != channelId) { // component could write more than one dirty-bits, so call the serialize func OnSerializeSafely(comp, s_UpdateWriter, false); continue; } if (OnSerializeSafely(comp, s_UpdateWriter, false)) { comp.ClearAllDirtyBits(); #if UNITY_EDITOR //UnityEditor.NetworkDetailStats.IncrementStat( // UnityEditor.NetworkDetailStats.NetworkDirection.Outgoing, // MsgType.UpdateVars, comp.GetType().Name, 1); #endif wroteData = true; } if (s_UpdateWriter.Position - oldPos > NetworkServer.maxPacketSize) { if (LogFilter.logWarn) { Debug.LogWarning("Large state update of " + (s_UpdateWriter.Position - oldPos) + " bytes for netId:" + netId + " from script:" + comp); } } } if (!wroteData) { // nothing to send.. this could be a script with no OnSerialize function setting dirty bits continue; } s_UpdateWriter.FinishMessage(); NetworkServer.SendWriterToReady(gameObject, s_UpdateWriter, channelId); } } }
public void RebuildObservers(bool initialize) { if (m_Observers == null) { return; } bool changed = false; bool result = false; HashSet <NetworkConnection> newObservers = new HashSet <NetworkConnection>(); HashSet <NetworkConnection> oldObservers = new HashSet <NetworkConnection>(m_Observers); for (int i = 0; i < m_NetworkBehaviours.Length; i++) { NetworkBehaviour comp = m_NetworkBehaviours[i]; result |= comp.OnRebuildObservers(newObservers, initialize); } if (!result) { // none of the behaviours rebuilt our observers, use built-in rebuild method if (initialize) { for (int i = 0; i < NetworkServer.connections.Count; i++) { var conn = NetworkServer.connections[i]; if (conn == null) { continue; } if (conn.isReady) { AddObserver(conn); } } for (int i = 0; i < NetworkServer.localConnections.Count; i++) { var conn = NetworkServer.localConnections[i]; if (conn == null) { continue; } if (conn.isReady) { AddObserver(conn); } } } return; } // apply changes from rebuild foreach (var conn in newObservers) { if (conn == null) { continue; } if (!conn.isReady) { if (LogFilter.logWarn) { Debug.LogWarning("Observer is not ready for " + gameObject + " " + conn); } continue; } if (initialize || !oldObservers.Contains(conn)) { // new observer conn.AddToVisList(this); if (LogFilter.logDebug) { Debug.Log("New Observer for " + gameObject + " " + conn); } changed = true; } } foreach (var conn in oldObservers) { if (!newObservers.Contains(conn)) { // removed observer conn.RemoveFromVisList(this, false); if (LogFilter.logDebug) { Debug.Log("Removed Observer for " + gameObject + " " + conn); } changed = true; } } // special case for local client. if (initialize) { for (int i = 0; i < NetworkServer.localConnections.Count; i++) { if (!newObservers.Contains(NetworkServer.localConnections[i])) { OnSetLocalVisibility(false); } } } if (!changed) { return; } m_Observers = new List <NetworkConnection>(newObservers); // rebuild hashset once we have the final set of new observers m_ObserverConnections.Clear(); for (int i = 0; i < m_Observers.Count; i++) { m_ObserverConnections.Add(m_Observers[i].connectionId); } }
internal void OnStartServer(bool allowNonZeroNetId) { if (m_IsServer) { return; } m_IsServer = true; if (m_LocalPlayerAuthority) { // local player on server has NO authority m_HasAuthority = false; } else { // enemy on server has authority m_HasAuthority = true; } m_Observers = new List <NetworkConnection>(); m_ObserverConnections = new HashSet <int>(); CacheBehaviours(); // If the instance/net ID is invalid here then this is an object instantiated from a prefab and the server should assign a valid ID if (netId.IsEmpty()) { m_NetId = GetNextNetworkId(); } else { if (allowNonZeroNetId) { //allowed } else { if (LogFilter.logError) { Debug.LogError("Object has non-zero netId " + netId + " for " + gameObject); } return; } } if (LogFilter.logDev) { Debug.Log("OnStartServer " + gameObject + " GUID:" + netId); } NetworkServer.instance.SetLocalObjectOnServer(netId, gameObject); for (int i = 0; i < m_NetworkBehaviours.Length; i++) { NetworkBehaviour comp = m_NetworkBehaviours[i]; try { comp.OnStartServer(); } catch (Exception e) { Debug.LogError("Exception in OnStartServer:" + e.Message + " " + e.StackTrace); } } if (NetworkClient.active && NetworkServer.localClientActive) { // there will be no spawn message, so start the client here too ClientScene.SetLocalObject(netId, gameObject); OnStartClient(); } if (m_HasAuthority) { OnStartAuthority(); } }
public void InitializeBehaviour(NetworkBehaviour beh, int cmdHash) { m_Behaviour = beh; m_CmdHash = cmdHash; }