private bool ProcessScenes() { var scenePaths = AssetDatabase.FindAssets("t:Scene") .Select(n => AssetDatabase.GUIDToAssetPath(n)) .ToList(); bool hasDirtyScenes = false; for (int i = 0; i < EditorSceneManager.sceneCount; i++) { if (EditorSceneManager.GetSceneAt(i).isDirty) { hasDirtyScenes = true; break; } } if (hasDirtyScenes && !EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()) { return(false); } var oldSceneSetup = EditorSceneManager.GetSceneManagerSetup(); try { for (int i = 0; i < scenePaths.Count; i++) { var scenePath = scenePaths[i]; if (EditorUtility.DisplayCancelableProgressBar("Scanning Scenes", "Scene " + (i + 1) + "/" + scenePaths.Count + " - " + scenePath, (float)i / scenePaths.Count)) { return(false); } EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Single); var sceneGOs = UnityEngine.Object.FindObjectsOfType <GameObject>(); foreach (var go in sceneGOs) { if ((go.hideFlags & HideFlags.DontSaveInBuild) == 0) { foreach (var component in go.GetComponents <ISerializationCallbackReceiver>()) { component.OnBeforeSerialize(); var prefabSupporter = component as ISupportsPrefabSerialization; if (prefabSupporter != null) { // Also force a serialization of the object's prefab modifications, in case there are unknown types in there List <UnityEngine.Object> objs = null; var mods = UnitySerializationUtility.DeserializePrefabModifications(prefabSupporter.SerializationData.PrefabModifications, prefabSupporter.SerializationData.PrefabModificationsReferencedUnityObjects); UnitySerializationUtility.SerializePrefabModifications(mods, ref objs); } } } } } // Load a new empty scene that will be unloaded immediately, just to be sure we completely clear all changes made by the scan EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single); } finally { try { EditorUtility.DisplayProgressBar("Restoring scene setup", "", 0.5f); EditorSceneManager.RestoreSceneManagerSetup(oldSceneSetup); } finally { EditorUtility.ClearProgressBar(); } } return(true); }
public bool ScanScenes(string[] scenePaths, bool includeSceneDependencies, bool showProgressBar) { if (scenePaths.Length == 0) { return(true); } bool formerForceEditorModeSerialization = UnitySerializationUtility.ForceEditorModeSerialization; try { UnitySerializationUtility.ForceEditorModeSerialization = true; bool hasDirtyScenes = false; for (int i = 0; i < EditorSceneManager.sceneCount; i++) { if (EditorSceneManager.GetSceneAt(i).isDirty) { hasDirtyScenes = true; break; } } if (hasDirtyScenes && !EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()) { return(false); } var oldSceneSetup = EditorSceneManager.GetSceneManagerSetup(); try { for (int i = 0; i < scenePaths.Length; i++) { var scenePath = scenePaths[i]; if (showProgressBar && DisplaySmartUpdatingCancellableProgressBar("Scanning scenes for AOT support", "Scene " + (i + 1) + "/" + scenePaths.Length + " - " + scenePath, (float)i / scenePaths.Length)) { return(false); } if (!System.IO.File.Exists(scenePath)) { Debug.LogWarning("Skipped AOT scanning scene '" + scenePath + "' for a file not existing at the scene path."); continue; } Scene openScene = default(Scene); try { openScene = EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Single); } catch { Debug.LogWarning("Skipped AOT scanning scene '" + scenePath + "' for throwing exceptions when trying to load it."); continue; } var sceneGOs = Resources.FindObjectsOfTypeAll <GameObject>(); foreach (var go in sceneGOs) { if (go.scene != openScene) { continue; } if ((go.hideFlags & HideFlags.DontSaveInBuild) == 0) { foreach (var component in go.GetComponents <ISerializationCallbackReceiver>()) { try { this.allowRegisteringScannedTypes = true; component.OnBeforeSerialize(); var prefabSupporter = component as ISupportsPrefabSerialization; if (prefabSupporter != null) { // Also force a serialization of the object's prefab modifications, in case there are unknown types in there List <UnityEngine.Object> objs = null; var mods = UnitySerializationUtility.DeserializePrefabModifications(prefabSupporter.SerializationData.PrefabModifications, prefabSupporter.SerializationData.PrefabModificationsReferencedUnityObjects); UnitySerializationUtility.SerializePrefabModifications(mods, ref objs); } } finally { this.allowRegisteringScannedTypes = false; } } } } } // Load a new empty scene that will be unloaded immediately, just to be sure we completely clear all changes made by the scan // Sometimes this fails for unknown reasons. In that case, swallow any exceptions, and just soldier on and hope for the best! // Additionally, also eat any debug logs that happen here, because logged errors can stop the build process, and we don't want // that to happen. UnityEngine.ILogger logger = null; if (Debug_Logger_Property != null) { logger = (UnityEngine.ILogger)Debug_Logger_Property.GetValue(null, null); } bool previous = true; try { if (logger != null) { previous = logger.logEnabled; logger.logEnabled = false; } EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single); } catch { } finally { if (logger != null) { logger.logEnabled = previous; } } } finally { if (oldSceneSetup != null && oldSceneSetup.Length > 0) { if (showProgressBar) { EditorUtility.DisplayProgressBar("Restoring scene setup", "", 1.0f); } EditorSceneManager.RestoreSceneManagerSetup(oldSceneSetup); } } if (includeSceneDependencies) { for (int i = 0; i < scenePaths.Length; i++) { var scenePath = scenePaths[i]; if (showProgressBar && DisplaySmartUpdatingCancellableProgressBar("Scanning scene dependencies for AOT support", "Scene " + (i + 1) + "/" + scenePaths.Length + " - " + scenePath, (float)i / scenePaths.Length)) { return(false); } string[] dependencies = AssetDatabase.GetDependencies(scenePath, recursive: true); foreach (var dependency in dependencies) { this.ScanAsset(dependency, includeAssetDependencies: false); // All dependencies of this asset were already included recursively by Unity } } } return(true); } finally { if (showProgressBar) { EditorUtility.ClearProgressBar(); } UnitySerializationUtility.ForceEditorModeSerialization = formerForceEditorModeSerialization; } }
public bool ScanScenes(string[] scenePaths, bool includeSceneDependencies, bool showProgressBar) { if (scenePaths.Length == 0) { return(true); } bool formerForceEditorModeSerialization = UnitySerializationUtility.ForceEditorModeSerialization; try { UnitySerializationUtility.ForceEditorModeSerialization = true; bool hasDirtyScenes = false; for (int i = 0; i < EditorSceneManager.sceneCount; i++) { if (EditorSceneManager.GetSceneAt(i).isDirty) { hasDirtyScenes = true; break; } } if (hasDirtyScenes && !EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()) { return(false); } var oldSceneSetup = EditorSceneManager.GetSceneManagerSetup(); try { for (int i = 0; i < scenePaths.Length; i++) { var scenePath = scenePaths[i]; if (showProgressBar && EditorUtility.DisplayCancelableProgressBar("Scanning scenes for AOT support", "Scene " + (i + 1) + "/" + scenePaths.Length + " - " + scenePath, (float)i / scenePaths.Length)) { return(false); } EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Single); var sceneGOs = UnityEngine.Object.FindObjectsOfType <GameObject>(); foreach (var go in sceneGOs) { if ((go.hideFlags & HideFlags.DontSaveInBuild) == 0) { foreach (var component in go.GetComponents <ISerializationCallbackReceiver>()) { try { this.allowRegisteringScannedTypes = true; component.OnBeforeSerialize(); var prefabSupporter = component as ISupportsPrefabSerialization; if (prefabSupporter != null) { // Also force a serialization of the object's prefab modifications, in case there are unknown types in there List <UnityEngine.Object> objs = null; var mods = UnitySerializationUtility.DeserializePrefabModifications(prefabSupporter.SerializationData.PrefabModifications, prefabSupporter.SerializationData.PrefabModificationsReferencedUnityObjects); UnitySerializationUtility.SerializePrefabModifications(mods, ref objs); } } finally { this.allowRegisteringScannedTypes = false; } } } } } // Load a new empty scene that will be unloaded immediately, just to be sure we completely clear all changes made by the scan EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single); } finally { if (oldSceneSetup != null && oldSceneSetup.Length > 0) { if (showProgressBar) { EditorUtility.DisplayProgressBar("Restoring scene setup", "", 1.0f); } EditorSceneManager.RestoreSceneManagerSetup(oldSceneSetup); } } if (includeSceneDependencies) { for (int i = 0; i < scenePaths.Length; i++) { var scenePath = scenePaths[i]; if (showProgressBar && EditorUtility.DisplayCancelableProgressBar("Scanning scene dependencies for AOT support", "Scene " + (i + 1) + "/" + scenePaths.Length + " - " + scenePath, (float)i / scenePaths.Length)) { return(false); } string[] dependencies = AssetDatabase.GetDependencies(scenePath, recursive: true); foreach (var dependency in dependencies) { this.ScanAsset(dependency, includeAssetDependencies: false); // All dependencies of this asset were already included recursively by Unity } } } return(true); } finally { if (showProgressBar) { EditorUtility.ClearProgressBar(); } UnitySerializationUtility.ForceEditorModeSerialization = formerForceEditorModeSerialization; } }