private void HandleOnInitializeSceneStripping()
        {
            if (!EditorApplication.isPlayingOrWillChangePlaymode)
            {
                return;
            }

            if (playModeStripping == StrippingType.None)
            {
                return;
            }

                        #if DEV_MODE
            Debug.Assert(EditorApplication.isPlayingOrWillChangePlaymode);
                        #endif

            // Strip hierarchy from all other scenes which are fully loaded at this time (it should be safe since they are loaded, so we'll do this no matter which stripping method is used).
            int sceneCount = SceneManager.sceneCount;
            for (int s = 0; s < sceneCount; s++)
            {
                var scene = SceneManager.GetSceneAt(s);
                if (scene.isLoaded && playModeStrippingHandledForScenes.Add(scene))
                {
                    HierarchyFolderUtility.ApplyStrippingType(scene, playModeStripping);
                }
                                #if DEV_MODE
                else
                {
                    Debug.Log("scene " + scene.name + ".isLoaded=" + scene.isLoaded);
                }
                                #endif
            }
        }
Example #2
0
        private static void HandlePrefabOrPrefabInstanceStateLocking(HierarchyFolder hierarchyFolder, bool isPrefabAsset)
        {
            var transform = hierarchyFolder.transform;

            transform.hideFlags = HideFlags.NotEditable;

            var gameObject = transform.gameObject;

            if (gameObject.layer != DefaultLayer)
            {
                gameObject.layer = DefaultLayer;
            }

            hierarchyFolder.hideFlags = HideFlags.HideInInspector;

            if (!isPrefabAsset)
            {
                return;
            }

            if (HierarchyFolderUtility.HasSupernumeraryComponents(hierarchyFolder))
            {
                HierarchyFolderUtility.UnmakeHierarchyFolder(gameObject, hierarchyFolder);
                return;
            }

            HierarchyFolderUtility.ResetTransformStateWithoutAffectingChildren(transform);
        }
Example #3
0
        private void OnHierarchyChangedInPlayModeFlattened()
        {
            if (this == null)
            {
                EditorApplication.hierarchyChanged -= OnHierarchyChangedInPlayModeFlattened;
                return;
            }

            OnHierarchyChangedShared();

                        #if DEV_MODE
            if (transform.childCount > 0)
            {
                if (HierarchyFolderUtility.NowStripping)
                {
                    Debug.LogWarning(name + " child count is " + transform.childCount + " but won't flatten because HierarchyFolderUtility.NowStripping already true.", gameObject);
                }
                else
                {
                    Debug.Log(name + " child count " + transform.childCount + ". Flattening now...", gameObject);
                }
            }
                        #endif

            if (transform.childCount > 0 && !HierarchyFolderUtility.NowStripping)
            {
                int moveToIndex = HierarchyFolderUtility.GetLastChildIndexInFlatMode(gameObject);
                for (int n = transform.childCount - 1; n >= 0; n--)
                {
                    var child = transform.GetChild(n);
                    child.SetParent(null, true);
                    child.SetSiblingIndex(moveToIndex);
                }
            }
        }
        /// <summary>
        /// Called once a scene has fully finished loading. This happens AFTER Awake methods have been called.
        /// This methods serves to purposes:
        /// 1. When Play Mode Stripping Method is set to Entire Scene When Loaded, this is the main way that scenes are stripped.
        /// 2. When Play Mode Stripping Method is set to Individually During Awake, this might handles stripping some inactive HierarchyFolders Awake methods were not fired for handling them.
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="mode"></param>
        private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
        {
                        #if DEV_MODE
            Debug.Assert(scene.isLoaded);
            Debug.Assert(scene.IsValid());
                        #endif

                        #if DEV_MODE
            Debug.Log("OnSceneLoaded(" + scene.name + ")");
                        #endif

            if (playModeStripping == StrippingType.None)
            {
                return;
            }

            if (!EditorApplication.isPlayingOrWillChangePlaymode)
            {
                return;
            }

            if (!playModeStrippingHandledForScenes.Add(scene))
            {
                return;
            }

            HierarchyFolderUtility.ApplyStrippingType(scene, playModeStripping);
        }
        private static void OnPostProcessScene()
        {
            // This will also get called when entering Playmode, when SceneManager.LoadScene is called,
            // but we only want to do stripping just after building the Scene.
            if (Application.isPlaying)
            {
                return;
            }

            var preferences = HierarchyFolderPreferences.Get();

            if (preferences == null)
            {
                Debug.LogWarning("Failed to find Hierarchy Folder Preferences asset; will not strip hierarchy folders from build.");
                return;
            }

            if (!preferences.removeFromScenes)
            {
                if (!preferences.warnWhenNotRemovedFromBuild || warnedAboutRemoveFromBuildDisabled)
                {
                    return;
                }

                warnedAboutRemoveFromBuildDisabled = true;
                if (EditorUtility.DisplayDialog("Warning: Hierarchy Folder Stripping Disabled", "This is a reminder that you have disabled stripping of hierarchy folders from builds. This will result in suboptimal performance and is not recommended when making a release build.", "Continue Anyway", "Enable Stripping"))
                {
                    return;
                }
            }

            HierarchyFolderUtility.ApplyStrippingTypeToAllLoadedScenes(StrippingType.FlattenHierarchyAndRemoveGameObject);
        }
Example #6
0
    /// <summary>
    /// Sets parent Transform of child, with option to skip Hierarchy Folders.
    /// When <paramref name="skipHierarchyFolders"/> is false will also automatically handle Flatten Hierarchy play mode behaviour (when enabled in preferences).
    /// </summary>
    /// <param name="child"> Child whose parent is being set. </param>
    /// <param name="parent"> New parent for child. </param>
    /// <param name="worldPositionStays"></param>
    /// <param name="skipHierarchyFolders">
    /// If true then Hierarchy Folders will be skipped when determining the parent. If <paramref name="parent"/> and all parents it might have are hierarchy folders,
    /// then <paramref name="child"/> will be moved to hierarchy root.
    /// </param>
    public static void SetParent([NotNull] this Transform child, [CanBeNull] Transform parent, bool worldPositionStays, bool skipHierarchyFolders)
    {
                #if UNITY_EDITOR
        if (parent != null && parent.gameObject.IsHierarchyFolder())
        {
            if (skipHierarchyFolders)
            {
                child.SetParent(parent.GetParent(true), worldPositionStays);
            }
            else if (HierarchyFolderPreferences.FlattenHierarchy)
            {
                int moveToIndex    = HierarchyFolderUtility.GetLastChildIndexInFlatMode(parent.gameObject);
                var parentOfFolder = parent.parent;
                child.transform.SetParent(parentOfFolder, worldPositionStays);
                if (moveToIndex < 0)
                {
                                        #if DEV_MODE
                    Debug.LogWarning("GetLastChildIndexInFlatMode result < 0");
                                        #endif
                    return;
                }
                child.transform.SetSiblingIndex(moveToIndex);
                return;
            }
        }
                #endif

        child.transform.SetParent(parent, worldPositionStays);
    }
        private void OnSceneGUI(SceneView sceneView)
        {
            var eventType = Event.current.type;

            // Reset hierarchy folder transform states immediately on mouse up in case user
            // just finished moving a hierarchy folder transform in the hierarchy view.
            switch (eventType)
            {
            case EventType.MouseDown:
                                #if DISABLE_TRANSFORM_GIZMOS
                if (Tools.current != Tool.Move && Tools.current != Tool.Transform && Tools.current != Tool.Rotate && Tools.current != Tool.Scale && Tools.current != Tool.Rect)
                {
                    break;
                }
                var selected = Selection.gameObjects;
                for (int n = selected.Length - 1; n >= 0; n--)
                {
                    if (selected[n].IsHierarchyFolder())
                    {
                        editorToolTempDisabled = Tools.current;
                        Tools.current          = Tool.View;
                        break;
                    }
                }
                break;
                                #endif
            case EventType.MouseUp:
            case EventType.MouseLeaveWindow:
                                #if DISABLE_TRANSFORM_GIZMOS
                if (editorToolTempDisabled != Tool.None)
                {
                    Tools.current          = editorToolTempDisabled;
                    editorToolTempDisabled = Tool.None;
                }
                break;
                                #endif
            case EventType.DragExited:
            case EventType.DragPerform:
            case EventType.Ignore:
            case EventType.Used:
            case EventType.KeyDown:
            case EventType.KeyUp:
                                        #if DEV_MODE && DEBUG_ON_SCENE_GUI
                Debug.Log("HierarchyFolderManager.OnSceneGUI(" + Event.current.type + ")");
                                        #endif
                break;

            default:
                return;
            }

            hierarchyFolders.RemoveAll(isNull);
            hierarchyFolders.Sort(compareHierarchyDepth);

            for (int n = hierarchyFolders.Count - 1; n >= 0; n--)
            {
                HierarchyFolderUtility.ResetTransformStateWithoutAffectingChildren(hierarchyFolders[n].transform);
            }
        }
Example #8
0
        internal static void CreateHierarchyFolderParent()
        {
            int count = Selection.transforms.Length;

            var members = new Transform[count];

            Array.Copy(Selection.transforms, 0, members, 0, count);
            Array.Sort(members, SortByHierarchyOrder);

            var firstMember           = members[0];
            var hierarchyFolderParent = firstMember.parent;

            var folder = CreateHierarchyFolderInternal(firstMember is RectTransform);

            // if not all selected have the same parent, then create folders as last item in hierarchy
            for (int n = 1; n < count; n++)
            {
                if (members[n].parent != hierarchyFolderParent)
                {
                    hierarchyFolderParent = null;
                    break;
                }
            }

            if (hierarchyFolderParent != null)
            {
                folder.transform.UndoableSetParent(hierarchyFolderParent, "Hierarchy Folder Parent");
            }
            int hierarchyFolderSiblingIndex = firstMember.GetSiblingIndex();

            folder.transform.SetSiblingIndex(hierarchyFolderSiblingIndex);

            Undo.RegisterCreatedObjectUndo(folder, "Hierarchy Folder Parent");

                        #if UNITY_EDITOR
            if (EditorApplication.isPlayingOrWillChangePlaymode && HierarchyFolderPreferences.Get().playModeBehaviour == StrippingType.FlattenHierarchy)
            {
                int moveToIndex = HierarchyFolderUtility.GetLastChildIndexInFlatMode(folder);
                for (int n = count - 1; n >= 0; n--)
                {
                    Undo.SetTransformParent(members[n], hierarchyFolderParent, "Hierarchy Folder Parent");
                    members[n].SetSiblingIndex(moveToIndex);
                }
                return;
            }
                        #endif

            for (int n = 0; n < count; n++)
            {
                Undo.SetTransformParent(members[n], folder.transform, "Hierarchy Folder Parent");
                members[n].SetAsLastSibling();
            }

            Selection.activeGameObject = folder;
        }
        internal void OnReset(HierarchyFolder hierarchyFolder)
        {
            if (HierarchyFolderUtility.HasSupernumeraryComponents(hierarchyFolder))
            {
                Debug.LogWarning("Can't convert GameObject with extraneous components into a Hierarchy Folder.", hierarchyFolder.gameObject);
                TurnIntoNormalGameObject(hierarchyFolder);
                return;
            }

            var gameObject = hierarchyFolder.gameObject;

            if (HierarchyFolderPreferences.Get().foldersInPrefabs == HierachyFoldersInPrefabs.NotAllowed)
            {
                bool isPrefabInstance = gameObject.IsConnectedPrefabInstance();
                if (isPrefabInstance || gameObject.IsPrefabAssetOrOpenInPrefabStage())
                {
                    OnHierarchyFolderDetectedOnAPrefabAndNotAllowed(hierarchyFolder, isPrefabInstance);
                    return;
                }
            }

            var transform = hierarchyFolder.transform;

            HierarchyFolderUtility.ResetTransformStateWithoutAffectingChildren(transform);

            // Don't hide transform in prefabs or prefab instances to avoid internal Unity exceptions
            if (!gameObject.IsPrefabAssetOrInstance())
            {
                transform.hideFlags = HideFlags.HideInInspector | HideFlags.NotEditable;
            }
            else
            {
                transform.hideFlags = HideFlags.NotEditable;
            }
            hierarchyFolder.hideFlags = HideFlags.HideInInspector | HideFlags.NotEditable;
            EditorUtility.SetDirty(transform);
            gameObject.isStatic = true;
            EditorUtility.SetDirty(hierarchyFolder);
            var preferences = HierarchyFolderPreferences.Get();

            if (preferences.autoNameOnAdd)
            {
                if (gameObject.name.Equals("GameObject", StringComparison.Ordinal) || gameObject.name.StartsWith("GameObject (", StringComparison.Ordinal))
                {
                    gameObject.name = preferences.defaultName;
                }
                else
                {
                    ApplyNamingPattern(hierarchyFolder);
                }
            }

            EditorUtility.SetDirty(gameObject);
        }
        private void UnmakeHierarchyFolder([CanBeNull] HierarchyFolder hierarchyFolder)
        {
            // If this hierarchy folder has already been destroyed we should abort.
            if (hierarchyFolder == null)
            {
                return;
            }

            destroying.Remove(hierarchyFolder);

            HierarchyFolderUtility.UnmakeHierarchyFolder(hierarchyFolder.gameObject, hierarchyFolder);
        }
Example #11
0
    /// <summary>
    /// Sets parent Transform of child, with option to skip Hierarchy Folders.
    /// When <paramref name="skipHierarchyFolders"/> is false will also automatically handle Flatten Hierarchy play mode behaviour (when enabled in preferences).
    /// </summary>
    /// <param name="child"> Child whose parent is being set. </param>
    /// <param name="parent"> New parent for child. </param>
    /// <param name="worldPositionStays"></param>
    /// <param name="skipHierarchyFolders">
    /// If true then Hierarchy Folders will be skipped when determining the parent. If <paramref name="parent"/> and all parents it might have are hierarchy folders,
    /// then <paramref name="child"/> will be moved to hierarchy root.
    /// </param>
    public static void UndoableSetParent([NotNull] this Transform child, [CanBeNull] Transform parent, string undoName, bool skipHierarchyFolders = false)
    {
                #if UNITY_EDITOR
        if (parent != null && parent.gameObject.IsHierarchyFolder())
        {
            if (skipHierarchyFolders)
            {
                if (!Application.isPlaying)
                {
                    Undo.SetTransformParent(child, parent.GetParent(true), undoName);                     //NOTE: Doesn't support worldPositionStays=false
                }
                else
                {
                    child.SetParent(parent.GetParent(true), true);
                }
            }
            else if (HierarchyFolderPreferences.FlattenHierarchy)
            {
                int moveToIndex    = HierarchyFolderUtility.GetLastChildIndexInFlatMode(parent.gameObject);
                var parentOfFolder = parent.parent;

                if (!Application.isPlaying)
                {
                    Undo.SetTransformParent(child, parentOfFolder, undoName);                     //NOTE: Doesn't support worldPositionStays=false
                }
                else
                {
                    child.transform.SetParent(parentOfFolder, true);
                }

                if (moveToIndex < 0)
                {
                                        #if DEV_MODE
                    Debug.LogWarning("GetLastChildIndexInFlatMode result < 0");
                                        #endif
                    return;
                }
                child.transform.SetSiblingIndex(moveToIndex);
                return;
            }
        }

        if (!Application.isPlaying)
        {
            Undo.SetTransformParent(child, parent, undoName);
            return;
        }
                #endif

        child.transform.SetParent(parent, true);
    }
        private void OnHierarchyChangedInPlayModeFlattened()
        {
            hierarchyFolders.RemoveAll(isNull);
            hierarchyFolders.Sort(compareHierarchyDepth);

            for (int n = 0, count = hierarchyFolders.Count - 1; n < count; n++)
            {
                var hierarchyFolder = hierarchyFolders[n];

                // Only process scene objects, not prefabs.
                if (!hierarchyFolder.gameObject.scene.IsValid())
                {
                    continue;
                }

                OnHierarchyChangedShared(hierarchyFolder);

                var transform = hierarchyFolder.transform;

                                #if DEV_MODE
                if (transform.childCount > 0)
                {
                    if (HierarchyFolderUtility.NowStripping)
                    {
                        Debug.LogWarning(hierarchyFolder.name + " child count is " + transform.childCount + " but won't flatten because HierarchyFolderUtility.NowStripping already true.", hierarchyFolder);
                    }
                    else
                    {
                        Debug.Log(hierarchyFolder.name + " child count " + transform.childCount + ". Flattening now...", hierarchyFolder);
                    }
                }
                                #endif

                if (transform.childCount > 0 && !HierarchyFolderUtility.NowStripping)
                {
                    // todo: should we keep track of flattened children in play mode? Or only for prefabs?
                    // Would there be benefits to keeping track of them?
                    // Could select them when hierarchy folder is double clicked in hierarchy view?
                    // Could draw some sort of bounds around the children in the hierarchy?!!!
                    int moveToIndex = HierarchyFolderUtility.GetLastChildIndexInFlatMode(transform.gameObject);
                    for (int c = transform.childCount - 1; c >= 0; c--)
                    {
                        var child = transform.GetChild(c);
                        child.SetParent(null, true);
                        child.SetSiblingIndex(moveToIndex);
                    }
                }
            }

            hierarchyFolders.RemoveAll(isNull);
        }
        private static void StripPrefab(GameObject root, StrippingType strippingType)
        {
            var transform  = root.transform;
            int childCount = transform.childCount;
            var children   = new Transform[childCount];

            for (int n = 0; n < childCount; n++)
            {
                children[n] = transform.GetChild(n);
            }
            for (int n = 0; n < childCount; n++)
            {
                HierarchyFolderUtility.CheckForAndRemoveHierarchyFoldersInChildren(children[n], strippingType, true);
            }
        }
Example #14
0
        private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
        {
                        #if DEV_MODE
            Debug.Assert(playModeStripping != StrippingType.None);
            Debug.Assert(scene.isLoaded);
                        #endif

            if (!playModeStrippingHandledForScenes.Add(scene))
            {
                return;
            }

            playModeStrippingHandledForScenes.Add(scene);
            HierarchyFolderUtility.ApplyStrippingType(scene, playModeStripping);
        }
        private void OnHierarchyChangedInEditMode()
        {
            hierarchyFolders.RemoveAll(isNull);
            hierarchyFolders.Sort(compareHierarchyDepth);

                        #if DEV_MODE && DEBUG_HIERARCHY_CHANGED
            Debug.Log("OnHierarchyChangedInEditMode with hierarchyFolders=" + hierarchyFolders.Count);
                        #endif

            bool prefabsNotAllowed = HierarchyFolderPreferences.Get().foldersInPrefabs == HierachyFoldersInPrefabs.NotAllowed;

            for (int n = 0, count = hierarchyFolders.Count - 1; n < count; n++)
            {
                var hierarchyFolder = hierarchyFolders[n];

                // Only process scene objects, not prefabs.
                if (!hierarchyFolder.gameObject.scene.IsValid())
                {
                    continue;
                }

                if (prefabsNotAllowed && hierarchyFolder.gameObject.IsConnectedPrefabInstance())
                {
                    OnHierarchyFolderDetectedOnAPrefabAndNotAllowed(hierarchyFolder, true);
                    count = hierarchyFolders.Count;
                    continue;
                }

                // If has RectTransform child convert Transform component into RectTransform
                // to avoid child RectTransform values being affected by the parent hierarchy folders.
                // For performance reasons only first child is checked.
                var transform = hierarchyFolder.transform;
                if (transform.GetFirstChild(true) is RectTransform && !(transform is RectTransform))
                {
                                        #if DEV_MODE
                    Debug.LogWarning("Converting Hierarchy Folder " + hierarchyFolder.name + " Transform into RectTransform because it had a RectTransform child.", hierarchyFolder);
                                        #endif

                    HierarchyFolderUtility.ForceResetTransformStateWithoutAffectingChildren(transform, true);
                }

                ApplyNamingPattern(hierarchyFolder);

                OnHierarchyChangedShared(hierarchyFolder);
            }

            hierarchyFolders.RemoveAll(isNull);
        }
Example #16
0
        private void ConvertToGameObjectIfHierarchyFolder()
        {
            var gameObject = AssetDatabase.LoadAssetAtPath <GameObject>(assetImporter.assetPath);

            if (gameObject == null)
            {
                return;
            }

            if (!gameObject.IsHierarchyFolder())
            {
                return;
            }

            Debug.LogWarning("Hierarchy Folders can only exist in the scene and as such can't be prefabs. Converting into a normal GameObject.", gameObject);
            HierarchyFolderUtility.UnmakeHierarchyFolder(gameObject, gameObject.GetComponent <HierarchyFolder>());
        }
Example #17
0
        private static void OnPostProcessScene()
        {
            if (!Application.isPlaying)
            {
                var preferences = HierarchyFolderPreferences.Get();
                if (!preferences.removeFromBuild)
                {
                    if (!preferences.warnWhenNotRemovedFromBuild || warnedAboutRemoveFromBuildDisabled)
                    {
                        return;
                    }

                    warnedAboutRemoveFromBuildDisabled = true;
                    if (EditorUtility.DisplayDialog("Warning: Hierarchy Folder Stripping Disabled", "This is a reminder that you have disabled stripping of hierarchy folders from builds. This will result in suboptimal performance and is not recommended when making a release build.", "Continue Anyway", "Enable Stripping"))
                    {
                        return;
                    }
                }

                HierarchyFolderUtility.ApplyStrippingTypeToAllLoadedScenes(StrippingType.FlattenHierarchyAndRemoveGameObject);
            }
        }
Example #18
0
        public PlayModeStripper(StrippingType setStrippingType, PlayModeStrippingMethod setStrippingMethod)
        {
            playModeStripping       = setStrippingType;
            playModeStrippingMethod = setStrippingMethod;

            if (playModeStripping == StrippingType.None)
            {
                return;
            }

            SceneManager.sceneLoaded               += OnSceneLoaded;
            SceneManager.sceneUnloaded             += OnSceneUnloaded;
            EditorApplication.playModeStateChanged += OnPlayModeStateChanged;

            for (int s = 0, scount = SceneManager.sceneCount; s < scount; s++)
            {
                var scene = SceneManager.GetSceneAt(s);
                if (scene.isLoaded && playModeStrippingHandledForScenes.Add(scene))
                {
                    HierarchyFolderUtility.ApplyStrippingType(scene, playModeStripping);
                }
            }
        }
        internal void OnHierarchyChangedShared(HierarchyFolder hierarchyFolder)
        {
            if (HierarchyFolderUtility.HasSupernumeraryComponents(hierarchyFolder))
            {
                // Prevent warning message being logged multiple times.
                if (!destroying.Add(hierarchyFolder))
                {
                    return;
                }

                Debug.LogWarning("Hierarchy Folder \"" + hierarchyFolder.name + "\" contained extraneous components.\nThis is not supported since Hierarchy Folders are stripped from builds. Converting into a normal GameObject now.", hierarchyFolder.gameObject);

                                #if DEV_MODE
                foreach (var component in hierarchyFolder.gameObject.GetComponents <Component>())
                {
                    Debug.Log(component.GetType().Name);
                }
                                #endif

                TurnIntoNormalGameObject(hierarchyFolder);
            }

            HierarchyFolderUtility.ResetTransformStateWithoutAffectingChildren(hierarchyFolder.transform);
        }
Example #20
0
        protected override void OnHeaderGUI()
        {
            if (!staticSetupDone)
            {
                StaticSetup();
            }

            if (defaultEditor == null)
            {
                defaultEditor = CreateEditor(targets, defaultEditorType);
                if (defaultEditor == null)
                {
                    return;
                }
            }

            var    gameObject = targets.Length == 0 ? null : targets[0] as GameObject;
            bool   isHierarchyFolder;
            string tagWas;
            int    layerWas;

            if (gameObject != null)
            {
                tagWas            = gameObject.tag;
                layerWas          = gameObject.layer;
                isHierarchyFolder = gameObject.IsHierarchyFolder();
            }
            else
            {
                isHierarchyFolder = false;
                tagWas            = null;
                layerWas          = 0;
            }

            defaultOnHeaderGUI.Invoke(defaultEditor, null);

            if (!isHierarchyFolder || gameObject == null)
            {
                return;
            }

                        #if POWER_INSPECTOR
            if (InspectorUtility.NowDrawingInspectorPart != InspectorPart.None)
            {
                return;
            }
                        #endif

            if (!gameObject.CompareTag(tagWas))
            {
                if (EditorUtility.DisplayDialog("Change Tag", "Do you want to set tag to " + gameObject.tag + " for all child objects?", "Yes, change children", "Cancel"))
                {
                    gameObject.SetTagForAllChildren(gameObject.tag);
                }
                gameObject.tag = "Untagged";
            }

            if (gameObject.layer != layerWas)
            {
                gameObject.layer = layerWas;
            }

            bool isHierarchyFolderPrefab = gameObject.IsPrefabAssetOrOpenInPrefabStage();
            var  label = isHierarchyFolderPrefab ? prefabHierarchyFolderInfoLabel : hierarchyFolderInfoLabel;
            EditorGUILayout.LabelField(label, EditorStyles.helpBox);

            // Ensure the transform state is kept reset if users somehow manage to modify it for example through a custom transform editor.
            // The transform should have at least the NotEditable flag though, so this is unlikely to occur.
            for (int i = targets.Length - 1; i >= 0; i--)
            {
                gameObject = targets[i] as GameObject;
                if (gameObject == null)
                {
                    continue;
                }

                var  transform         = gameObject.transform;
                bool transformIsHidden = (transform.hideFlags & HideFlags.HideInInspector) == HideFlags.HideInInspector;
                if (transformIsHidden)
                {
                    continue;
                }

                bool transformNotEditable = (transform.hideFlags & HideFlags.NotEditable) == HideFlags.NotEditable;
                if (transformNotEditable)
                {
                    continue;
                }

                HierarchyFolderUtility.ResetTransformStateWithoutAffectingChildren(transform);
            }

            if (isHierarchyFolderPrefab)
            {
                return;
            }

            var labelRect = GUILayoutUtility.GetLastRect();

            var backgroundRect = labelRect;
            backgroundRect.x     += 0f;
            backgroundRect.y      = 5f;
            backgroundRect.width  = 36f;
            backgroundRect.height = 36f;
            EditorGUI.DrawRect(backgroundRect, backgroundColor);

            var folderIconRect = labelRect;
            folderIconRect.x     += 3f;
            folderIconRect.y      = 5f;
            folderIconRect.width  = 30f;
            folderIconRect.height = 30f;
            GUI.DrawTexture(folderIconRect, folderIcon);
        }
Example #21
0
        private void HandleOnSceneObjectAwake(GameObject gameObject)
        {
            if (playModeStripping == StrippingType.None)
            {
                return;
            }

                        #if DEV_MODE
            Debug.Assert(EditorApplication.isPlayingOrWillChangePlaymode);
                        #endif

            var scene = gameObject.scene;
            if (playModeStrippingHandledForScenes.Contains(scene))
            {
                return;
            }

            switch (playModeStrippingMethod)
            {
            case PlayModeStrippingMethod.EntireSceneWhenLoaded:
                if (!scene.isLoaded)
                {
                    return;
                }
                break;

            case PlayModeStrippingMethod.IndividuallyDuringAwake:
                if (!scene.isLoaded)
                {
                    var rootTransform = gameObject.transform.transform.root;
                    HashSet <Transform> handledRootObjects;
                    if (!playModeStrippingHandledForSceneRootObjects.TryGetValue(gameObject.scene, out handledRootObjects))
                    {
                        playModeStrippingHandledForSceneRootObjects.Add(gameObject.scene, new HashSet <Transform>()
                        {
                            rootTransform
                        });
                    }
                    else if (!handledRootObjects.Add(rootTransform))
                    {
                        return;
                    }
                    HierarchyFolderUtility.CheckForAndRemoveHierarchyFoldersInChildren(gameObject.transform.root, playModeStripping);
                    return;
                }
                break;
            }

            playModeStrippingHandledForScenes.Add(gameObject.scene);

            try
            {
                HierarchyFolderUtility.ApplyStrippingType(gameObject.scene, playModeStripping);
            }
            catch (System.ArgumentException e)            // catch "ArgumentException: The scene is not loaded." which can occur when using PlayModeStrippingMethod.EntireSceneImmediate.
            {
                Debug.LogError("Exception encountered while stripping Hierarchy Folders from scene " + gameObject.scene.name + " for play mode using method " + playModeStripping + ". You may need to switch to a different play mode stripping method in preferences.\n" + e);
                playModeStrippingHandledForScenes.Remove(gameObject.scene);

                                #if DEV_MODE
                Debug.Assert(!HierarchyFolderUtility.NowStripping);
                                #endif
            }
        }
 private void TurnIntoNormalGameObject()
 {
     HierarchyFolderUtility.UnmakeHierarchyFolder(gameObject, this);
 }
Example #23
0
 private void UnmakeHierarchyFolder()
 {
     HierarchyFolderUtility.UnmakeHierarchyFolder(gameObject, this);
 }
        private void HandleOnSceneObjectAwake(GameObject gameObject)
        {
            if (!EditorApplication.isPlayingOrWillChangePlaymode)
            {
                return;
            }

            if (playModeStripping == StrippingType.None)
            {
                                #if DEV_MODE && DEBUG_AWAKE_STRIPPING
                Debug.Log("Aborting stripping for gameObject because playModeStripping was None.");
                                #endif
                return;
            }

                        #if DEV_MODE
            Debug.Assert(EditorApplication.isPlayingOrWillChangePlaymode);
                        #endif

            var scene = gameObject.scene;

            // Strip hierarchy from all other scenes which are fully loaded at this time (it should be safe since they are loaded, so we'll do this no matter which stripping method is used).
            int sceneCount = SceneManager.sceneCount;
            if (sceneCount > 1)
            {
                for (int s = 0; s < sceneCount; s++)
                {
                    var otherScene = SceneManager.GetSceneAt(s);
                    if (otherScene != scene && otherScene.isLoaded && playModeStrippingHandledForScenes.Add(otherScene))
                    {
                        HierarchyFolderUtility.ApplyStrippingType(otherScene, playModeStripping);
                    }
                }
            }

            // Handle on-the-fly stripping for prefab instances being instantiated in play mode.
            if (gameObject.IsPartOfInstantiatedPrefabInstance())
            {
                var transform = gameObject.transform;
                if (transform.parent == null)
                {
                    HashSet <Transform> handledRootObjects;
                    if (!playModeStrippingHandledForSceneRootObjects.TryGetValue(gameObject.scene, out handledRootObjects))
                    {
                        playModeStrippingHandledForSceneRootObjects.Add(gameObject.scene, new HashSet <Transform>()
                        {
                            transform
                        });
                    }
                    else if (!handledRootObjects.Add(transform))
                    {
                                                #if DEV_MODE && DEBUG_AWAKE_STRIPPING
                        Debug.Log("Aborting stripping for prefab instance because handledRootObjects already contained transform " + transform.name + ".");
                                                #endif
                        return;
                    }
                }

                                #if DEV_MODE && DEBUG_STRIP_PREFAB_INSTANCE
                Debug.Log("Prefab instance detected: " + gameObject.name + " with prefabInstanceStatus=" + PrefabUtility.GetPrefabInstanceStatus(gameObject));
                                #endif

                // We unfortunately can't use DestroyImmediate with any GameObjects inside a prefab instance just being instantiated, or it would result in:
                // "UnityException: Instantiate failed because the clone was destroyed during creation. This can happen if DestroyImmediate is called in MonoBehaviour.Awake."
                HierarchyFolderUtility.CheckForAndRemoveHierarchyFoldersInChildren(gameObject.transform, playModeStripping, false);
                return;
            }

            if (playModeStrippingHandledForScenes.Contains(scene))
            {
                                #if DEV_MODE && DEBUG_AWAKE_STRIPPING
                Debug.Log("Aborting stripping for gameObject because stripping already handled for scene " + scene.name);
                                #endif
                return;
            }

            switch (playModeStrippingMethod)
            {
            case PlayModeStrippingMethod.EntireSceneWhenLoaded:
                if (!scene.isLoaded)
                {
                                                #if DEV_MODE && DEBUG_AWAKE_STRIPPING
                    Debug.Log("Aborting stripping for " + gameObject.name + " because scene " + scene.name + " not loaded and using stripping method EntireSceneWhenLoaded.");
                                                #endif
                    return;
                }
                break;

            case PlayModeStrippingMethod.IndividuallyDuringAwake:
                // If entire scene is not yet loaded, then only strip GameObjects nested under the root transform of this hierarchy folder (might be safer this way, so won't try to Destroy uninitialized objects).
                if (!scene.isLoaded)
                {
                    var rootTransform = gameObject.transform.root;
                    HashSet <Transform> handledRootObjects;
                    if (!playModeStrippingHandledForSceneRootObjects.TryGetValue(gameObject.scene, out handledRootObjects))
                    {
                        playModeStrippingHandledForSceneRootObjects.Add(gameObject.scene, new HashSet <Transform>()
                        {
                            rootTransform
                        });
                    }
                    else if (!handledRootObjects.Add(rootTransform))
                    {
                                                        #if DEV_MODE && DEBUG_AWAKE_STRIPPING
                        Debug.Log("Aborting stripping for gameObject because scene " + scene.name + " not loaded and handledRootObjects already contained transform.root " + rootTransform.name + ".");
                                                        #endif
                        return;
                    }

                                                #if DEV_MODE && DEBUG_STRIP_SCENE
                    Debug.Log("CheckForAndRemoveHierarchyFoldersInChildren(" + gameObject.transform.root.name + ").");
                                                #endif

                    HierarchyFolderUtility.CheckForAndRemoveHierarchyFoldersInChildren(gameObject.transform.root, playModeStripping, true);
                    return;
                }

                                        #if DEV_MODE && DEBUG_STRIP_SCENE
                Debug.Log("Scene " + scene.name + " was not loaded yet...");
                                        #endif

                // If entire scene is loaded, then can just strip the entire scene fully, as it should be safe to do so.
                break;
            }

            playModeStrippingHandledForScenes.Add(scene);

            try
            {
                HierarchyFolderUtility.ApplyStrippingType(scene, playModeStripping);
            }
            catch (System.ArgumentException e)            // catch "ArgumentException: The scene is not loaded." which can occur when using PlayModeStrippingMethod.EntireSceneImmediate.
            {
                Debug.LogError("Exception encountered while stripping Hierarchy Folders from scene " + scene.name + " for play mode using method " + playModeStripping + ". You may need to switch to a different play mode stripping method in preferences.\n" + e);
                playModeStrippingHandledForScenes.Remove(scene);

                                #if DEV_MODE
                Debug.Assert(!HierarchyFolderUtility.NowStripping);
                                #endif
            }
        }
Example #25
0
 private static void UnmakeHierarchyFolder(GameObject gameObject)
 {
     Debug.LogWarning(HierarchyFolderMessages.PrefabNotAllowed, gameObject);
     HierarchyFolderUtility.UnmakeHierarchyFolder(gameObject, gameObject.GetComponent <HierarchyFolder>());
 }