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 } }
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 } }