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);
            }
        }
        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 #3
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
            }
        }