Exemplo n.º 1
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();
                }
            }
        }
Exemplo n.º 2
0
        public virtual void Convert(Entity entity, EntityManager dstManager,
                                    GameObjectConversionSystem conversionSystem)
        {
            // 客户端与服务端都需要注册序列化器.
            var collection = default(GhostPrefabCollectionComponent);

            var conversionTarget = GetConversionTarget(dstManager.World);

            // 查询出可用的Ghost预制体
            _enabledGhosts = GetGhosts();

            collection.ServerPrefabs = dstManager.CreateEntity();
            var serverPrefabs = new NativeList <GhostPrefabBuffer>(Allocator.Temp);
            int ghostType     = 0;

            foreach (var ghost in _enabledGhosts)
            {
                var    orig = ghost.prefab.Type;
                Entity ent  =
                    GameObjectConversionUtility.ConvertGameObjectHierarchy(ghost.prefab.gameObject,
                                                                           conversionSystem.ForkSettings(1));

                dstManager.SetComponentData(ent, new GhostComponent {
                    GhostType = ghostType
                });

                GhostPrefabType prefabType = orig == GhostAuthoringComponent.ClientInstanceType.Interpolated
                    ? GhostPrefabType.InterpolatedClient
                    : GhostPrefabType.PredictedClient;

                var ghostPrefab = new GhostPrefabBuffer
                {
                    Value      = ent,
                    GhostType  = ghostType,
                    PrefabType = prefabType,
                    IsOwner    = orig == GhostAuthoringComponent.ClientInstanceType.OwnerPredicted &&
                                 ghost.prefab.GetComponent <GhostOwnerAuthoringComponent>()
                };

                NativeArray <ComponentType> componentTypes = dstManager.GetComponentTypes(ent);
                componentTypes.Dispose();

                serverPrefabs.Add(ghostPrefab);
                ++ghostType;
            }

            dstManager.AddBuffer <GhostPrefabBuffer>(collection.ServerPrefabs).AddRange(serverPrefabs);
            serverPrefabs.Dispose();


            //=======================================================================================================
            // 普通的预制体转换后的Entity
            PrefabCollectionSystem prefabCollectionSystem =
                dstManager.World.GetOrCreateSystem <PrefabCollectionSystem>();

            prefabCollectionSystem.Prefabs =
                new NativeArray <PrefabItem>(this.ghostCollectionConfig.Prefabs.Count, Allocator.Persistent);

            for (int i = 0; i < this.ghostCollectionConfig.Prefabs.Count; i++)
            {
                Entity ent = conversionSystem.GetPrimaryEntity(ghostCollectionConfig.Prefabs[i]);


                var item = new PrefabItem
                {
                    Value = ent,
                    Type  = i
                };
                prefabCollectionSystem.Prefabs[i] = item;
            }

            // Debug.Log($"转换Prefabs: {prefabCollectionSystem.Prefabs.Length}");
            //=======================================================================================================


            if (conversionTarget == TargetWorld.Client)
            {
                ghostType = 0;
                collection.ClientInterpolatedPrefabs = dstManager.CreateEntity();
                collection.ClientPredictedPrefabs    = dstManager.CreateEntity();
                var predictedList    = new NativeList <GhostPrefabBuffer>(Allocator.Temp);
                var interpolatedList = new NativeList <GhostPrefabBuffer>(Allocator.Temp);

                foreach (var ghost in _enabledGhosts)
                {
                    var orig = ghost.prefab.Type;

                    ghost.prefab.Type = GhostAuthoringComponent.ClientInstanceType.Interpolated;
                    Entity interpolatedEnt =
                        GameObjectConversionUtility.ConvertGameObjectHierarchy(ghost.prefab.gameObject,
                                                                               conversionSystem.ForkSettings(2));
                    dstManager.SetComponentData(interpolatedEnt, new GhostComponent {
                        GhostType = ghostType
                    });
                    interpolatedList.Add(new GhostPrefabBuffer
                    {
                        Value      = interpolatedEnt,
                        GhostType  = ghostType,
                        PrefabType = GhostPrefabType.InterpolatedClient
                    });

                    ghost.prefab.Type = GhostAuthoringComponent.ClientInstanceType.Predicted;
                    Entity predictedEnt =
                        GameObjectConversionUtility.ConvertGameObjectHierarchy(ghost.prefab.gameObject,
                                                                               conversionSystem.ForkSettings(2));
                    dstManager.SetComponentData(predictedEnt, new GhostComponent {
                        GhostType = ghostType
                    });
                    predictedList.Add(new GhostPrefabBuffer
                    {
                        Value      = predictedEnt,
                        GhostType  = ghostType,
                        PrefabType = GhostPrefabType.PredictedClient
                    });

                    ghost.prefab.Type = orig;
                    ++ghostType;
                }

                dstManager.AddBuffer <GhostPrefabBuffer>(collection.ClientPredictedPrefabs).AddRange(predictedList);
                dstManager.AddBuffer <GhostPrefabBuffer>(collection.ClientInterpolatedPrefabs)
                .AddRange(interpolatedList);

                predictedList.Dispose();
                interpolatedList.Dispose();
            }

            dstManager.AddComponentData(entity, collection);
        }