コード例 #1
0
        private ulong VariantPopup(SerializedComponentData comp, ulong variantHash)
        {
            if (!GhostAuthoringModifiers.VariantsCache.TryGetValue(comp.managedType.FullName, out var list))
            {
                return(0);
            }

            int index = 0;

            if (variantHash != 0)
            {
                index = list.FindIndex(v => v.Attribute.VariantHash == variantHash);
                if (index < 0)
                {
                    Debug.LogWarning($"Variation with hash {variantHash} not found.");
                    index = 0;
                }
            }
            var names = list.Select(i => i.Attribute.DisplayName).ToArray();
            var idx   = EditorGUILayout.Popup(new GUIContent("Serialization Variant"), index, names);

            GUI.changed |= idx != index;
            return(list[idx].Attribute.VariantHash);
        }
コード例 #2
0
        void ShowComponent(ref SerializedComponentData comp)
        {
            GUIStyle style                  = new GUIStyle(EditorStyles.foldoutHeader);
            var      prefabType             = comp.attribute != null?comp.attribute.PrefabType:GhostPrefabType.All;
            var      ownerPredictedSendType = comp.attribute != null?comp.attribute.OwnerPredictedSendType:GhostSendType.All;
            var      sendForChildren        = comp.attribute != null ? comp.attribute.SendDataForChildEntity : true;

            ulong variantHash = 0;
            int   index       = GetPrefabModifier(comp.name, comp.gameObject, out var modifier);

            //Apply prefab modifier only if they are meant to be different than the default.
            if (modifier != null)
            {
                if (modifier.PrefabType != GhostAuthoringComponent.ComponentOverride.UseDefaultValue)
                {
                    prefabType = (GhostPrefabType)modifier.PrefabType;
                }
                if (modifier.OwnerPredictedSendType != GhostAuthoringComponent.ComponentOverride.UseDefaultValue)
                {
                    ownerPredictedSendType = (GhostSendType)modifier.OwnerPredictedSendType;
                }
                if (modifier.SendToChild != GhostAuthoringComponent.ComponentOverride.UseDefaultValue)
                {
                    sendForChildren = modifier.SendToChild == 0 ? false : true;
                }
                variantHash = modifier.ComponentVariant;
            }
            bool hasDataToSend = comp.fields.Length > 0 && (comp.entityIndex == 0 || sendForChildren);

            style.fontStyle = modifier == null
                ? hasDataToSend ? FontStyle.Bold : FontStyle.Normal
                : hasDataToSend ? FontStyle.BoldAndItalic : FontStyle.Italic;
            var text = String.Format("{0}{1} ({2}/{3}/{4}){5}",
                                     comp.entityIndex != 0 ? "Child " + (comp.entityIndex - 1).ToString() + ": " : "",
                                     comp.name, (prefabType & GhostPrefabType.Server) != 0 ? "S" : "-",
                                     (prefabType & GhostPrefabType.InterpolatedClient) != 0 ? "IC" : "-",
                                     (prefabType & GhostPrefabType.PredictedClient) != 0 ? "PC" : "-",
                                     modifier != null?"*":"");

            comp.isExpanded = EditorGUILayout.BeginFoldoutHeaderGroup(comp.isExpanded, text, style);
            var  foldoutRect        = GUILayoutUtility.GetLastRect();
            bool canModifyComponent = comp.managedType.GetCustomAttribute <DontSupportPrefabOverrides>() == null;

            if (comp.isExpanded)
            {
                var             modPrefab    = modifier != null && modifier.PrefabType != GhostAuthoringComponent.ComponentOverride.UseDefaultValue;
                var             modSendChild = modifier != null && modifier.SendToChild != GhostAuthoringComponent.ComponentOverride.UseDefaultValue;
                var             modSendType  = modifier != null && modifier.OwnerPredictedSendType != GhostAuthoringComponent.ComponentOverride.UseDefaultValue;
                GhostPrefabType newPrefab    = prefabType;
                EditorGUI.BeginChangeCheck();
                using (new EditorGUI.DisabledGroupScope(!canModifyComponent))
                {
                    modPrefab    = AuthoringEditorHelper.ShowPrefabType(modPrefab, prefabType, ref newPrefab);
                    modSendChild = AuthoringEditorHelper.ShowSendChild(comp, modSendChild, ref sendForChildren);
                    modSendType  = AuthoringEditorHelper.ShowSendType(modSendType, ref ownerPredictedSendType);
                    //Changing variant will change the defaults values for the ghost attribute for the type
                    variantHash = VariantPopup(comp, variantHash);
                }
                if (EditorGUI.EndChangeCheck())
                {
                    //If the prefab use default values there is not need to have a modifier. Remove
                    bool useAllDefaults = !modPrefab && !modSendType && !modSendChild && variantHash == 0;
                    if (useAllDefaults && modifier != null)
                    {
                        ComponentOverrides.RemoveAt(index);
                        //Refresh the comp field to the theid default variant version
                        ExtractComponentInfo((target as GhostAuthoringComponent)?.gameObject, ref comp);
                        EditorUtility.SetDirty(target);
                    }
                    else if (!useAllDefaults)
                    {
                        if (modifier == null)
                        {
                            modifier = AddModifier(comp.name, comp.gameObject);
                        }
                        if (modifier.ComponentVariant != variantHash)
                        {
                            //Refresh the component fields values to reflect the current selected variant
                            modifier.ComponentVariant = variantHash;
                            ExtractComponentInfo((target as GhostAuthoringComponent)?.gameObject, ref comp);
                        }
                        modifier.PrefabType = modPrefab
                            ? (int)newPrefab
                            : GhostAuthoringComponent.ComponentOverride.UseDefaultValue;
                        modifier.OwnerPredictedSendType = modSendType
                            ? (int)ownerPredictedSendType
                            : GhostAuthoringComponent.ComponentOverride.UseDefaultValue;
                        modifier.SendToChild = modSendChild
                            ? sendForChildren ? 1 : 0
                            : GhostAuthoringComponent.ComponentOverride.UseDefaultValue;
                        EditorUtility.SetDirty(target);
                    }
                }

                if ((prefabType & GhostPrefabType.Server) != 0)
                {
                    EditorGUILayout.Separator();
                    EditorGUI.BeginDisabledGroup(true);
                    EditorGUILayout.LabelField("Fields");
                    for (int fi = 0; fi < comp.fields.Length; ++fi)
                    {
                        ShowField(comp.fields[fi]);
                    }

                    EditorGUI.EndDisabledGroup();
                }
            }
            EditorGUILayout.EndFoldoutHeaderGroup();
            //Display context menu when user press the left mouse button that have some shortcuts. Options available:
            // - Remove the component from the ghost (set the prefab to type to 0)
            // - Reset the component to its default (remove the overrides)
            if (canModifyComponent && Event.current.type == EventType.MouseDown && Event.current.button == 1)
            {
                if (foldoutRect.Contains(Event.current.mousePosition))
                {
                    var typeFullName = comp.name;
                    var gameObject   = comp.gameObject;
                    //Show context menu with some options
                    var menu = new GenericMenu();
                    menu.AddItem(new GUIContent("Remove Component"), false, () =>
                    {
                        //Add modifier if not present
                        if (modifier == null)
                        {
                            modifier = AddModifier(typeFullName, gameObject);
                        }
                        modifier.PrefabType = 0;
                        EditorUtility.SetDirty(target);
                    });
                    if (modifier != null)
                    {
                        menu.AddItem(new GUIContent("Reset Default"), false, () =>
                        {
                            ComponentOverrides.RemoveAt(index);
                            EditorUtility.SetDirty(target);
                        });
                    }
                    else
                    {
                        menu.AddDisabledItem(new GUIContent("Reset Default"));
                    }
                    menu.ShowAsContext();
                }
            }
        }