void CalculatePrefabStatus()
        {
            m_PlayModeObjects               = false;
            m_IsAsset                       = false;
            m_ImmutableSelf                 = false;
            m_ImmutableSourceAsset          = false;
            m_IsDisconnected                = false;
            m_IsMissing                     = false;
            m_IsPrefabInstanceAnyRoot       = true;
            m_IsPrefabInstanceOutermostRoot = true;
            m_AllOfSamePrefabType           = true;
            PrefabAssetType      firstType   = PrefabUtility.GetPrefabAssetType(targets[0]);
            PrefabInstanceStatus firstStatus = PrefabUtility.GetPrefabInstanceStatus(targets[0]);

            foreach (var o in targets)
            {
                var                  go     = (GameObject)o;
                PrefabAssetType      type   = PrefabUtility.GetPrefabAssetType(go);
                PrefabInstanceStatus status = PrefabUtility.GetPrefabInstanceStatus(go);
                if (type != firstType || status != firstStatus)
                {
                    m_AllOfSamePrefabType = false;
                }

                if (Application.IsPlaying(go))
                {
                    m_PlayModeObjects = true;
                }
                if (!PrefabUtility.IsAnyPrefabInstanceRoot(go))
                {
                    m_IsPrefabInstanceAnyRoot = false; // Conservative is false if any is false
                }
                if (!m_IsPrefabInstanceAnyRoot || !PrefabUtility.IsOutermostPrefabInstanceRoot(go))
                {
                    m_IsPrefabInstanceOutermostRoot = false; // Conservative is false if any is false
                }
                if (PrefabUtility.IsPartOfPrefabAsset(go))
                {
                    m_IsAsset = true; // Conservative is true if any is true
                }
                if (m_IsAsset && PrefabUtility.IsPartOfImmutablePrefab(go))
                {
                    m_ImmutableSelf = true; // Conservative is true if any is true
                }
                GameObject originalSourceOrVariant = PrefabUtility.GetOriginalSourceOrVariantRoot(go);
                if (originalSourceOrVariant != null && PrefabUtility.IsPartOfImmutablePrefab(originalSourceOrVariant))
                {
                    m_ImmutableSourceAsset = true; // Conservative is true if any is true
                }
                if (PrefabUtility.IsDisconnectedFromPrefabAsset(go))
                {
                    m_IsDisconnected = true;
                }
                if (PrefabUtility.IsPrefabAssetMissing(go))
                {
                    m_IsMissing = true;
                }
            }
        }
        void SetPrefabModeButtonVisibility(GameObjectTreeViewItem item)
        {
            item.showPrefabModeButton = false;

            GameObject go = item.objectPPTR as GameObject;

            if (go == null)
            {
                return;
            }

            if (!PrefabUtility.IsPartOfAnyPrefab(go))
            {
                return;
            }

            if (!PrefabUtility.IsAnyPrefabInstanceRoot(go))
            {
                return;
            }

            // Don't show button if prefab asset is missing
            if (PrefabUtility.GetPrefabInstanceStatus(go) == PrefabInstanceStatus.Connected)
            {
                var source = PrefabUtility.GetOriginalSourceOrVariantRoot(go);
                if (source == null)
                {
                    return;
                }

                // Don't show buttons for model prefabs but allow buttons for other immutables
                if (PrefabUtility.IsPartOfModelPrefab(source))
                {
                    return;
                }
            }
            else if (PrefabUtility.GetPrefabInstanceHandle(go) == null)
            {
                return;
            }
            else
            {
                var assetPath = PrefabUtility.GetAssetPathOfSourcePrefab(go);
                var broken    = AssetDatabase.LoadMainAssetAtPath(assetPath) as BrokenPrefabAsset;
                if (broken == null || !broken.isPrefabFileValid)
                {
                    return;
                }
            }

            item.showPrefabModeButton = true;
        }
        void SetPrefabModeButtonVisibility(GameObjectTreeViewItem item)
        {
            item.showPrefabModeButton = false;

            GameObject go = item.objectPPTR as GameObject;

            if (go == null)
            {
                return;
            }

            if (!PrefabUtility.IsPartOfAnyPrefab(go))
            {
                return;
            }

            if (!PrefabUtility.IsAnyPrefabInstanceRoot(go))
            {
                return;
            }

            // Don't show button for disconnected prefab instances and if prefab asset is missing
            if (PrefabUtility.GetPrefabInstanceStatus(go) != PrefabInstanceStatus.Connected)
            {
                return;
            }

            var source = PrefabUtility.GetOriginalSourceOrVariantRoot(go);

            if (source == null)
            {
                return;
            }

            // Don't show buttons for model prefabs but allow buttons for other immutables
            if (PrefabUtility.IsPartOfModelPrefab(source))
            {
                return;
            }

            item.showPrefabModeButton = true;
        }
예제 #4
0
        void CalculatePrefabStatus()
        {
            m_IsPrefabInstanceAnyRoot = false;
            m_IsAsset             = false;
            m_AllOfSamePrefabType = true;
            PrefabAssetType      firstType   = PrefabUtility.GetPrefabAssetType(targets[0]);
            PrefabInstanceStatus firstStatus = PrefabUtility.GetPrefabInstanceStatus(targets[0]);

            foreach (GameObject go in targets)
            {
                PrefabAssetType      type   = PrefabUtility.GetPrefabAssetType(go);
                PrefabInstanceStatus status = PrefabUtility.GetPrefabInstanceStatus(go);
                if (type != firstType || status != firstStatus)
                {
                    m_AllOfSamePrefabType = false;
                }

                if (PrefabUtility.IsAnyPrefabInstanceRoot(go))
                {
                    m_IsPrefabInstanceAnyRoot = true;
                }
                if (m_IsPrefabInstanceAnyRoot)
                {
                    m_IsPrefabInstanceOutermostRoot = PrefabUtility.IsOutermostPrefabInstanceRoot(go);
                }
                if (PrefabUtility.IsPartOfPrefabAsset(go))
                {
                    m_IsAsset = true;
                }
                if (m_IsAsset && PrefabUtility.IsPartOfImmutablePrefab(go))
                {
                    m_ImmutableSelf = true;
                }
                GameObject originalSourceOrVariant = PrefabUtility.GetOriginalSourceOrVariantRoot(go);
                if (originalSourceOrVariant != null && PrefabUtility.IsPartOfImmutablePrefab(originalSourceOrVariant))
                {
                    m_ImmutableSourceAsset = true;
                }
            }
        }
        void SetPrefabModeButtonVisibility(GameObjectTreeViewItem item)
        {
            item.showPrefabModeButton = false;

            GameObject go = item.objectPPTR as GameObject;

            if (go == null)
            {
                return;
            }

            if (!PrefabUtility.IsPartOfAnyPrefab(go))
            {
                return;
            }

            if (!PrefabUtility.IsAnyPrefabInstanceRoot(go))
            {
                return;
            }

            // Don't show button for disconnected prefab instances and if prefab asset is missing
            if (PrefabUtility.GetPrefabInstanceStatus(go) != PrefabInstanceStatus.Connected)
            {
                return;
            }

            // We can't simply check if the go is part of an immutable prefab, since that would check the asset of the
            // outermost prefab this go is part of. Instead we have to check original source or variant root
            // - the same one that would get opened if clicking the arrow.
            var source = PrefabUtility.GetOriginalSourceOrVariantRoot(go);

            if (source == null || PrefabUtility.IsPartOfImmutablePrefab(source))
            {
                return;
            }

            item.showPrefabModeButton = true;
        }
        private void DoPrefabButtons()
        {
            if (!m_IsPrefabInstanceAnyRoot || m_IsAsset)
            {
                return;
            }

            using (new EditorGUI.DisabledScope(m_PlayModeObjects))
            {
                EditorGUILayout.BeginHorizontal(Styles.prefabButtonsHorizontalLayout);

                // Prefab information
                PrefabAssetType      singlePrefabType     = PrefabUtility.GetPrefabAssetType(target);
                PrefabInstanceStatus singleInstanceStatus = PrefabUtility.GetPrefabInstanceStatus(target);
                GUIContent           prefixLabel;
                if (targets.Length > 1)
                {
                    prefixLabel = Styles.goTypeLabelMultiple;
                }
                else
                {
                    prefixLabel = Styles.goTypeLabel[(int)singlePrefabType, (int)singleInstanceStatus];
                }

                if (prefixLabel != null)
                {
                    EditorGUILayout.BeginHorizontal(GUILayout.Width(kIconSize + Styles.tagFieldWidth));
                    GUILayout.FlexibleSpace();
                    if (m_IsDisconnected || m_IsMissing)
                    {
                        GUI.contentColor = GUI.skin.GetStyle("CN StatusWarn").normal.textColor;
                        GUILayout.Label(prefixLabel, EditorStyles.whiteLabel, GUILayout.ExpandWidth(false));
                        GUI.contentColor = Color.white;
                    }
                    else
                    {
                        GUILayout.Label(prefixLabel, GUILayout.ExpandWidth(false));
                    }
                    EditorGUILayout.EndHorizontal();
                }

                if (!m_IsMissing)
                {
                    using (new EditorGUI.DisabledScope(targets.Length > 1))
                    {
                        if (singlePrefabType == PrefabAssetType.Model)
                        {
                            // Open Model Prefab
                            if (GUILayout.Button(Styles.openString, EditorStyles.miniButtonLeft))
                            {
                                GameObject asset = PrefabUtility.GetOriginalSourceOrVariantRoot(target);
                                AssetDatabase.OpenAsset(asset);
                                GUIUtility.ExitGUI();
                            }
                        }
                        else
                        {
                            // Open non-Model Prefab
                            using (new EditorGUI.DisabledScope(m_ImmutableSourceAsset))
                            {
                                if (GUILayout.Button(Styles.openString, EditorStyles.miniButtonLeft))
                                {
                                    GameObject asset = PrefabUtility.GetOriginalSourceOrVariantRoot(target);
                                    PrefabStageUtility.OpenPrefab(AssetDatabase.GetAssetPath(asset), (GameObject)target, StageNavigationManager.Analytics.ChangeType.EnterViaInstanceInspectorOpenButton);
                                    GUIUtility.ExitGUI();
                                }
                            }
                        }
                    }

                    // Select prefab
                    if (GUILayout.Button(Styles.selectString, EditorStyles.miniButtonRight))
                    {
                        HashSet <GameObject> selectedAssets = new HashSet <GameObject>();
                        for (int i = 0; i < targets.Length; i++)
                        {
                            GameObject prefabGo = PrefabUtility.GetOriginalSourceOrVariantRoot(targets[i]);

                            // Because of legacy prefab references we have to have this extra step
                            // to make sure we ping the prefab asset correctly.
                            // Reason is that scene files created prior to making prefabs CopyAssets
                            // will reference prefabs as if they are serialized assets. Those references
                            // works fine but we are not able to ping objects loaded directly from the asset
                            // file, so we have to make sure we ping the metadata version of the prefab.
                            var assetPath = AssetDatabase.GetAssetPath(prefabGo);
                            selectedAssets.Add((GameObject)AssetDatabase.LoadMainAssetAtPath(assetPath));
                        }

                        Selection.objects = selectedAssets.ToArray();
                        if (Selection.gameObjects.Length == 1)
                        {
                            EditorGUIUtility.PingObject(Selection.activeObject);
                        }
                    }

                    // Should be EditorGUILayout.Space, except it does not have ExpandWidth set to false.
                    // Maybe we can change that?
                    GUILayoutUtility.GetRect(6, 6, GUILayout.ExpandWidth(false));

                    // Reserve space regardless of whether the button is there or not to avoid jumps in button sizes.
                    Rect rect = GUILayoutUtility.GetRect(Styles.overridesContent, Styles.overridesDropdown);
                    if (m_IsPrefabInstanceOutermostRoot)
                    {
                        if (EditorGUI.DropdownButton(rect, Styles.overridesContent, FocusType.Passive))
                        {
                            if (targets.Length > 1)
                            {
                                PopupWindow.Show(rect, new PrefabOverridesWindow(targets.Select(e => (GameObject)e).ToArray()));
                            }
                            else
                            {
                                PopupWindow.Show(rect, new PrefabOverridesWindow((GameObject)target));
                            }
                            GUIUtility.ExitGUI();
                        }
                    }
                }
                EditorGUILayout.EndHorizontal();
            }
        }
        internal bool DrawInspector()
        {
            serializedObject.Update();

            GameObject go = target as GameObject;

            // Don't let icon be null as it will create null reference exceptions.
            Texture2D icon = (Texture2D)(Styles.typelessIcon.image);

            // Leave iconContent to be default if multiple objects not the same type.
            if (m_AllOfSamePrefabType)
            {
                icon = PrefabUtility.GetIconForGameObject(go);
            }

            // Can't do this in OnEnable since it will cause Styles static initializer to be called and
            // access properties on EditorStyles static class before that one has been initialized.
            if (m_OpenPrefabContent == null)
            {
                if (targets.Length == 1)
                {
                    GameObject originalSourceOrVariant = PrefabUtility.GetOriginalSourceOrVariantRoot((GameObject)target);
                    if (originalSourceOrVariant != null)
                    {
                        m_OpenPrefabContent = new GUIContent(
                            Styles.openPrefab.text,
                            string.Format(Styles.openPrefab.tooltip, originalSourceOrVariant.name));
                    }
                }
                if (m_OpenPrefabContent == null)
                {
                    m_OpenPrefabContent = new GUIContent(Styles.openPrefab.text);
                }
            }

            EditorGUILayout.BeginHorizontal();
            Vector2 dropDownSize = EditorGUI.GetObjectIconDropDownSize(kIconSize, kIconSize);

            EditorGUI.ObjectIconDropDown(GUILayoutUtility.GetRect(dropDownSize.x, dropDownSize.y, GUILayout.ExpandWidth(false)), targets, true, icon, m_Icon);
            DrawPostIconContent();

            using (new EditorGUI.DisabledScope(m_ImmutableSelf))
            {
                EditorGUILayout.BeginVertical();
                {
                    EditorGUILayout.BeginHorizontal();
                    {
                        EditorGUILayout.BeginHorizontal(GUILayout.Width(Styles.tagFieldWidth));
                        {
                            GUILayout.FlexibleSpace();

                            // IsActive
                            EditorGUI.PropertyField(
                                GUILayoutUtility.GetRect(EditorStyles.toggle.padding.left, EditorGUIUtility.singleLineHeight, EditorStyles.toggle,
                                                         GUILayout.ExpandWidth(false)), m_IsActive, GUIContent.none);
                        }
                        EditorGUILayout.EndHorizontal();

                        // Disable the name field of root GO in prefab asset
                        using (new EditorGUI.DisabledScope(m_IsAsset && m_IsAssetRoot))
                        {
                            // Name
                            EditorGUILayout.DelayedTextField(m_Name, GUIContent.none, EditorStyles.boldTextField);
                        }

                        // Static flags toggle
                        DoStaticToggleField(go);

                        // Static flags dropdown
                        DoStaticFlagsDropDown(go);
                    }
                    EditorGUILayout.EndHorizontal();

                    EditorGUILayout.Space(EditorGUI.kControlVerticalSpacing);

                    EditorGUILayout.BeginHorizontal();
                    {
                        // Tag
                        DoTagsField(go);

                        EditorGUILayout.Space(EditorGUI.kDefaultSpacing, false);

                        // Layer
                        DoLayerField(go);
                    }
                    EditorGUILayout.EndHorizontal();
                }
                EditorGUILayout.EndVertical();
            }
            EditorGUILayout.EndHorizontal();

            // Prefab Toolbar
            if (EditorGUIUtility.comparisonViewMode == EditorGUIUtility.ComparisonViewMode.None)
            {
                EditorGUILayout.Space(EditorGUI.kControlVerticalSpacing);

                DoPrefabButtons();
            }

            serializedObject.ApplyModifiedProperties();

            return(true);
        }
예제 #8
0
        private void DoPrefabButtons(GameObject go)
        {
            // @TODO: If/when we support multi-editing of prefab/model instances,
            // handle it here. Only show prefab bar if all are same type?
            if (!m_IsPrefabInstanceAnyRoot)
            {
                return;
            }

            using (new EditorGUI.DisabledScope(EditorApplication.isPlayingOrWillChangePlaymode && PrefabStageUtility.GetPrefabStage(go) == null))
            {
                EditorGUILayout.BeginHorizontal(s_Styles.prefabButtonsHorizontalLayout);

                // Prefab information
                PrefabAssetType      prefabType     = PrefabUtility.GetPrefabAssetType(go);
                PrefabInstanceStatus instanceStatus = PrefabUtility.GetPrefabInstanceStatus(go);
                GUIContent           prefixLabel;
                if (targets.Length > 1)
                {
                    prefixLabel = s_Styles.goTypeLabelMultiple;
                }
                else
                {
                    prefixLabel = s_Styles.goTypeLabel[(int)prefabType, (int)instanceStatus];
                }

                if (prefixLabel != null)
                {
                    EditorGUILayout.BeginHorizontal(GUILayout.Width(kIconSize + s_Styles.tagFieldWidth));
                    GUILayout.FlexibleSpace();
                    if (PrefabUtility.IsDisconnectedFromPrefabAsset(go) || PrefabUtility.IsPrefabAssetMissing(go))
                    {
                        GUI.contentColor = GUI.skin.GetStyle("CN StatusWarn").normal.textColor;
                        GUILayout.Label(prefixLabel, EditorStyles.whiteLabel, GUILayout.ExpandWidth(false));
                        GUI.contentColor = Color.white;
                    }
                    else
                    {
                        GUILayout.Label(prefixLabel, GUILayout.ExpandWidth(false));
                    }
                    EditorGUILayout.EndHorizontal();
                }

                if (targets.Length > 1)
                {
                    GUILayout.Label("Instance Management Disabled", s_Styles.instanceManagementInfo);
                }
                else
                {
                    if (!PrefabUtility.IsPrefabAssetMissing(go))
                    {
                        if (prefabType == PrefabAssetType.Model)
                        {
                            // Open Model Prefab
                            if (GUILayout.Button("Open", "MiniButtonLeft"))
                            {
                                GameObject asset = PrefabUtility.GetOriginalSourceOrVariantRoot(target);
                                AssetDatabase.OpenAsset(asset);
                                GUIUtility.ExitGUI();
                            }
                        }
                        else
                        {
                            // Open non-Model Prefab
                            using (new EditorGUI.DisabledScope(m_ImmutableSourceAsset))
                            {
                                if (GUILayout.Button("Open", "MiniButtonLeft"))
                                {
                                    GameObject asset = PrefabUtility.GetOriginalSourceOrVariantRoot(target);
                                    PrefabStageUtility.OpenPrefab(AssetDatabase.GetAssetPath(asset), (GameObject)target, StageNavigationManager.Analytics.ChangeType.EnterViaInstanceInspectorOpenButton);
                                    GUIUtility.ExitGUI();
                                }
                            }
                        }

                        // Select prefab
                        if (GUILayout.Button("Select", "MiniButtonRight"))
                        {
                            Selection.activeObject = PrefabUtility.GetOriginalSourceOrVariantRoot(target);

                            // Because of legacy prefab references we have to have this extra step
                            // to make sure we ping the prefab asset correctly.
                            // Reason is that scene files created prior to making prefabs CopyAssets
                            // will reference prefabs as if they are serialized assets. Those references
                            // works fine but we are not able to ping objects loaded directly from the asset
                            // file, so we have to make sure we ping the metadata version of the prefab.
                            var assetPath = AssetDatabase.GetAssetPath(Selection.activeObject);
                            Selection.activeObject = AssetDatabase.LoadMainAssetAtPath(assetPath);

                            EditorGUIUtility.PingObject(Selection.activeObject);
                        }

                        // Should be EditorGUILayout.Space, except it does not have ExpandWidth set to false.
                        // Maybe we can change that?
                        GUILayoutUtility.GetRect(6, 6, GUILayout.ExpandWidth(false));

                        // Reserve space regardless of whether the button is there or not to avoid jumps in button sizes.
                        Rect rect = GUILayoutUtility.GetRect(s_Styles.overridesContent, s_Styles.overridesDropdown);
                        if (m_IsPrefabInstanceOutermostRoot)
                        {
                            if (EditorGUI.DropdownButton(rect, s_Styles.overridesContent, FocusType.Passive))
                            {
                                PopupWindow.Show(rect, new PrefabOverridesWindow(go));
                                GUIUtility.ExitGUI();
                            }
                        }
                    }
                }
                EditorGUILayout.EndHorizontal();
            }
        }