Inheritance: MonoBehaviour
Esempio n. 1
0
        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 && conn.isReady)
                        {
                            AddObserver(conn);
                        }
                    }

                    if (NetworkServer.localConnection != null && NetworkServer.localConnection.isReady)
                    {
                        AddObserver(NetworkServer.localConnection);
                    }
                }
                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)
            {
                if (!newObservers.Contains(NetworkServer.localConnection))
                {
                    OnSetLocalVisibility(false);
                }
            }

            if (changed)
            {
                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);
                }
            }
        }
Esempio n. 2
0
        internal void OnStartServer(bool allowNonZeroNetId)
        {
            if (m_IsServer)
            {
                return;
            }
            m_IsServer     = true;
            m_HasAuthority = !m_LocalPlayerAuthority;

            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)
                {
                    if (LogFilter.logError)
                    {
                        Debug.LogError("Object has non-zero netId " + netId + " for " + gameObject);
                    }
                    return;
                }
            }

            if (LogFilter.logDev)
            {
                Debug.Log("OnStartServer " + gameObject + " GUID:" + netId);
            }
            NetworkServer.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();
            }
        }
Esempio n. 3
0
 public void InitializeBehaviour(NetworkBehaviour beh, int cmdHash)
 {
     m_Behaviour = beh;
     m_CmdHash   = cmdHash;
 }
        public override void OnInspectorGUI()
        {
            if (!m_Initialized)
            {
                serializedObject.Update();
                SerializedProperty scriptProperty = serializedObject.FindProperty("m_Script");
                if (scriptProperty == null)
                {
                    return;
                }

                MonoScript targetScript = scriptProperty.objectReferenceValue as MonoScript;
                Init(targetScript);
            }

            EditorGUI.BeginChangeCheck();
            serializedObject.Update();

            // Loop through properties and create one field (including children) for each top level property.
            SerializedProperty property = serializedObject.GetIterator();
            bool expanded = true;

            while (property.NextVisible(expanded))
            {
                bool isSyncVar = m_SyncVarNames.Contains(property.name);
                if (property.propertyType == SerializedPropertyType.ObjectReference)
                {
                    if (property.name == "m_Script")
                    {
                        if (hideScriptField)
                        {
                            continue;
                        }

                        EditorGUI.BeginDisabledGroup(true);
                    }

                    EditorGUILayout.PropertyField(property, true);

                    if (isSyncVar)
                    {
                        GUILayout.Label(m_SyncVarIndicatorContent, EditorStyles.miniLabel, GUILayout.Width(EditorStyles.miniLabel.CalcSize(m_SyncVarIndicatorContent).x));
                    }

                    if (property.name == "m_Script")
                    {
                        EditorGUI.EndDisabledGroup();
                    }
                }
                else
                {
                    EditorGUILayout.BeginHorizontal();

                    EditorGUILayout.PropertyField(property, true);

                    if (isSyncVar)
                    {
                        GUILayout.Label(m_SyncVarIndicatorContent, EditorStyles.miniLabel, GUILayout.Width(EditorStyles.miniLabel.CalcSize(m_SyncVarIndicatorContent).x));
                    }

                    EditorGUILayout.EndHorizontal();
                }
                expanded = false;
            }
            serializedObject.ApplyModifiedProperties();
            EditorGUI.EndChangeCheck();

            // find SyncLists.. they are not properties.
            int syncListIndex = 0;

            foreach (FieldInfo field in serializedObject.targetObject.GetType().GetFields())
            {
                if (field.FieldType.BaseType != null && field.FieldType.BaseType.Name.Contains("SyncList"))
                {
                    m_ShowSyncLists[syncListIndex] = EditorGUILayout.Foldout(m_ShowSyncLists[syncListIndex], "SyncList " + field.Name + "  [" + field.FieldType.Name + "]");
                    if (m_ShowSyncLists[syncListIndex])
                    {
                        EditorGUI.indentLevel += 1;
                        if (field.GetValue(serializedObject.targetObject) is IEnumerable synclist)
                        {
                            int         index = 0;
                            IEnumerator enu   = synclist.GetEnumerator();
                            while (enu.MoveNext())
                            {
                                if (enu.Current != null)
                                {
                                    EditorGUILayout.LabelField("Item:" + index, enu.Current.ToString());
                                }
                                index += 1;
                            }
                        }
                        EditorGUI.indentLevel -= 1;
                    }
                    syncListIndex += 1;
                }
            }

            // only show SyncInterval if we have an OnSerialize function.
            // No need to show it if the class only has Cmds/Rpcs and no sync.
            if (m_SyncsAnything)
            {
                NetworkBehaviour networkBehaviour = target as NetworkBehaviour;
                if (networkBehaviour != null)
                {
                    // [0,2] should be enough. anything >2s is too laggy anyway.
                    serializedObject.FindProperty("syncInterval").floatValue = EditorGUILayout.Slider(
                        new GUIContent("Network Sync Interval",
                                       "Time in seconds until next change is synchronized to the client. '0' means send immediately if changed. '0.5' means only send changes every 500ms.\n(This is for state synchronization like SyncVars, SyncLists, OnSerialize. Not for Cmds, Rpcs, etc.)"),
                        networkBehaviour.syncInterval, 0, 2);
                    serializedObject.ApplyModifiedProperties();
                }
            }
        }
        public override void OnInspectorGUI()
        {
            if (!initialized)
            {
                serializedObject.Update();
                SerializedProperty scriptProperty = serializedObject.FindProperty("m_Script");
                if (scriptProperty == null)
                {
                    return;
                }

                MonoScript targetScript = scriptProperty.objectReferenceValue as MonoScript;
                Init(targetScript);
            }

#if ODIN_INSPECTOR
            base.Tree.DrawMonoScriptObjectField = !HideScriptField;

            // Draw the default properties with Odin; SyncVarDrawer<T> will take care of making SyncVar's look right, instead of the code below.
            DrawDefaultInspector();
#else
            EditorGUI.BeginChangeCheck();
            serializedObject.Update();

            // Loop through properties and create one field (including children) for each top level property.
            SerializedProperty property = serializedObject.GetIterator();
            bool expanded = true;
            while (property.NextVisible(expanded))
            {
                bool isSyncVar = syncVarNames.Contains(property.name);

                if (property.name == "m_Script")
                {
                    if (HideScriptField)
                    {
                        continue;
                    }

                    EditorGUI.BeginDisabledGroup(true);
                }

                if (isSyncVar)
                {
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.BeginVertical();
                }

                EditorGUILayout.PropertyField(property, true);

                if (isSyncVar)
                {
                    EditorGUILayout.EndVertical();
                    GUILayout.Label(syncVarIndicatorContent, EditorStyles.miniLabel, GUILayout.Width(EditorStyles.miniLabel.CalcSize(syncVarIndicatorContent).x));
                    EditorGUILayout.EndHorizontal();
                }

                if (property.name == "m_Script")
                {
                    EditorGUI.EndDisabledGroup();
                }

                expanded = false;
            }
            serializedObject.ApplyModifiedProperties();
            EditorGUI.EndChangeCheck();
#endif // ODIN_INSPECTOR

            // find SyncLists.. they are not properties.
            int syncListIndex = 0;
            foreach (FieldInfo field in serializedObject.targetObject.GetType().GetFields())
            {
                if (field.FieldType.BaseType != null && field.FieldType.BaseType.Name.Contains("SyncList"))
                {
                    showSyncLists[syncListIndex] = EditorGUILayout.Foldout(showSyncLists[syncListIndex], "SyncList " + field.Name + "  [" + field.FieldType.Name + "]");
                    if (showSyncLists[syncListIndex])
                    {
                        EditorGUI.indentLevel += 1;
                        if (field.GetValue(serializedObject.targetObject) is IEnumerable synclist)
                        {
                            int         index = 0;
                            IEnumerator enu   = synclist.GetEnumerator();
                            while (enu.MoveNext())
                            {
                                if (enu.Current != null)
                                {
                                    EditorGUILayout.LabelField("Item:" + index, enu.Current.ToString());
                                }
                                index += 1;
                            }
                        }
                        EditorGUI.indentLevel -= 1;
                    }
                    syncListIndex += 1;
                }
            }

            // does it sync anything? then show extra properties
            // (no need to show it if the class only has Cmds/Rpcs and no sync)
            if (syncsAnything)
            {
                NetworkBehaviour networkBehaviour = target as NetworkBehaviour;
                if (networkBehaviour != null)
                {
                    // syncMode
                    serializedObject.FindProperty("syncMode").enumValueIndex = (int)(SyncMode)
                                                                               EditorGUILayout.EnumPopup("Network Sync Mode", networkBehaviour.syncMode);

                    // syncInterval
                    // [0,2] should be enough. anything >2s is too laggy anyway.
                    serializedObject.FindProperty("syncInterval").floatValue = EditorGUILayout.Slider(
                        new GUIContent("Network Sync Interval",
                                       "Time in seconds until next change is synchronized to the client. '0' means send immediately if changed. '0.5' means only send changes every 500ms.\n(This is for state synchronization like SyncVars, SyncLists, OnSerialize. Not for Cmds, Rpcs, etc.)"),
                        networkBehaviour.syncInterval, 0, 2);

                    // apply
                    serializedObject.ApplyModifiedProperties();
                }
            }
        }