private void BuildNext() { //TODO: Must be fixed up to work with callback - scene saving does not work very well if done // immediately after load, which is why we need to make this into a async operation // of some sort. See unity case 336621. //Run through all scenes and build them based on the human readable representation. if (sceneQueue.Count > 0) { string textScene = sceneQueue.Dequeue(); Debug.Log("Building temp for: " + textScene); string result = TextSceneDeserializer.Load(EditorHelper.GetProjectFolder() + textScene, this.BuildNext); if (result.Length == 0) { EditorUtility.DisplayDialog("Scene does not exist", "Unable to find scene file: " + textScene + " Will be excluded from build", "OK"); BuildNext(); } else { binarySceneList.Add(result); } } else { FinishBuild(); } }
private void FinishBuild() { Debug.Log("Building " + binarySceneList.Count + " scenes: "); foreach (string scene in binarySceneList) { Debug.Log(scene); } if (buildPath != null) { BuildPipeline.BuildPlayer(binarySceneList.ToArray(), buildPath, buildTarget, BuildOptions.AutoRunPlayer); } else { Debug.Log("Temp scenes generated, no player will be built."); } if (sceneToLoad.Length > 0) { TextSceneDeserializer.Load(sceneToLoad); } }
public static void Save(string filePath) { if (EditorApplication.isPlayingOrWillChangePlaymode) { EditorUtility.DisplayDialog("Game is running", "You cannot save in Play-mode", "OK"); return; } Transform[] sceneObjects = Helper.GetObjectsOfType <Transform>(); List <Transform> sortedTransforms = new List <Transform>(); //Sort these to get a somewhat predictable output foreach (Transform o in sceneObjects) { //Only serialize root objects, children are handled by their parents if (o.parent == null) { sortedTransforms.Add(o); } } warnings = 0; sortedTransforms.Sort(CompareTransform); StringBuilder sceneText = new StringBuilder(); foreach (Transform o in sortedTransforms) { Serialize(sceneText, o.gameObject, 0); } //TODO: If the save didn't go without warnings, show a message/confirmation // dialog here. if (warnings > 0) { EditorUtility.DisplayDialog("ERROR: Scene not saved", "You had " + warnings + " errors or warnings during the save. Please fix them up and try again.", "OK"); return; } StreamWriter fileStream = File.CreateText(filePath); fileStream.Write(sceneText.ToString()); fileStream.Close(); Debug.Log("Wrote scene to file: " + filePath); string assetPath = filePath.Replace(EditorHelper.GetProjectFolder(), ""); Debug.Log("Reimporting: " + assetPath); //Import the asset. AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); Selection.activeObject = AssetDatabase.LoadAssetAtPath(assetPath, typeof(TextAsset)); TextSceneDeserializer.Load(filePath); }
public static void Load() { TextSceneDeserializer.Load(); }
public Status Update() { if (saveAndReload.Length == 0) { Debug.LogError("Invalid saveandreload name! Cancelling load/save process..."); return(Status.Failed); } if (saveAndReloadTimer > 0) { EditorUtility.DisplayProgressBar("Creating temp...", "Creating binary temp file for TextScene: " + state.ToString(), 1.0f - saveAndReloadTimer / SAVE_AND_RELOAD_FRAMES); saveAndReloadTimer--; return(Status.Working); } else { if (state == State.SaveTemp) { Debug.Log("SaveAndReload: " + saveAndReload); ///FIXME: Unity sometimes puts a lock on the scenes we try to save, this is a CRUEL way to ///get around it. /// ///Repro-steps: *Comment out the try/catch /// *Clean out tempscenes-folder. /// *Open up a scene (LEVEL1) from build settings, hit play /// *While playing, do something to make the game /// change to another level (LEVEL2). /// *Stop playing, you should now be back in the level where you /// hit play from. /// *Try to switch to the level you switched to in-game (LEVEL2). /// *You should, after the progress bar has completed, be prompted /// with an error saying Unity could not move file from Temp/Tempfile /// try { FileStream f = File.OpenWrite(saveAndReload); f.Close(); } catch { Debug.LogWarning("HACK: Getting around 'access denied' on temp files!"); //HACK: This seems to make Unity release the file so we can try to save it in a new go. if (!EditorApplication.OpenScene(saveAndReload)) { //Uh oh. Debug.LogError("HACK failed! What to do next?"); EditorUtility.ClearProgressBar(); return(Status.Failed); } TextSceneDeserializer.Load(EditorHelper.GetProjectFolder() + TextScene.TempToTextSceneFile(EditorApplication.currentScene), saveAndReloadCallback); return(Status.Working); } if (!EditorApplication.SaveScene(saveAndReload)) { Debug.LogError("Failed to save temp: " + saveAndReload); if (EditorUtility.DisplayDialog("ERROR", "Failed to save temp (" + saveAndReload + ") - try again?", "Yes", "No")) { saveAndReloadTimer = Mathf.RoundToInt(SAVE_AND_RELOAD_FRAMES); } else { return(Status.Failed); } EditorUtility.ClearProgressBar(); return(Status.Working); } state = State.CreateNew; saveAndReloadTimer = Mathf.RoundToInt(SAVE_AND_RELOAD_FRAMES); return(Status.Working); } else if (state == State.CreateNew) { EditorApplication.NewScene(); state = State.LoadTemp; saveAndReloadTimer = Mathf.RoundToInt(SAVE_AND_RELOAD_FRAMES); return(Status.Working); } else if (state == State.LoadTemp) { if (!EditorApplication.OpenScene(saveAndReload)) { Debug.LogError("Failed to load temp: " + saveAndReload); if (EditorUtility.DisplayDialog("ERROR", "Failed to load temp (" + saveAndReload + ") - try again?", "Yes", "No")) { saveAndReloadTimer = Mathf.RoundToInt(SAVE_AND_RELOAD_FRAMES); } else { return(Status.Failed); } EditorUtility.ClearProgressBar(); return(Status.Working); } string writtenFile = EditorHelper.GetProjectFolder() + EditorApplication.currentScene; DateTime writtenTime = File.GetLastWriteTime(writtenFile); Debug.Log("Wrote temp file at " + writtenTime); TextSceneMonitor.Instance.SetCurrentScene(EditorHelper.GetProjectFolder() + TextScene.TempToTextSceneFile(EditorApplication.currentScene)); saveAndReload = ""; EditorUtility.ClearProgressBar(); return(Status.Complete); } } Debug.LogError("Failing...."); return(Status.Failed); }
/// <summary> /// Regularly checks if something worthy of notifying the user happens. This includes /// unexpected scene changes (double-clicking .unity files), creating new scenes and /// source TextScene files having been changed between now and the time it was loaded. /// </summary> private void Update() { //HACK: To get around bug (TOOD: Insert case #) where Save immediately // after instantiating prefabs results in weird behaviour. if (process != null) { TextSceneTempCreator.Status status = process.Update(); switch (status) { case TextSceneTempCreator.Status.Failed: Debug.LogError("Creating temp files failed!"); process = null; break; case TextSceneTempCreator.Status.Complete: Debug.Log("Creating temp files succeeded!"); //FIXME: Either do this, or get a reference to the delegate and call // if after clearing tempCreator. The callback might // end up setting the tempCreator again, typically in a build-cycle, // for example. TextSceneTempCreator tempCreatorRef = process; process = null; tempCreatorRef.InvokeCallback(); break; default: break; } return; } //Did the user create a new scene? if (currentScene.Length > 0 && EditorApplication.currentScene.Length == 0) { if (CheckForChangedTemp()) { EditorApplication.NewScene(); } currentScene = ""; alarmingEditorScene = ""; TextSceneSerializer.SaveCurrent(); //Warn the user if the save scene dialog was cancelled. if (currentScene.Length == 0) { EditorUtility.DisplayDialog("New Scene", "You have started a new scene after using the TextScene system. Please use the TextScene menu to save it if you want to continue using the TextScene system", "OK"); } } //Try to detect when we go from a TextScene to a regular unit scene. if ((currentScene.Length > 0 && EditorApplication.currentScene.Length > 0) || (currentScene.Length == 0 && alarmingEditorScene.Length == 0)) { if (alarmingEditorScene != EditorApplication.currentScene) { string current = EditorApplication.currentScene; if (CheckForChangedTemp()) { EditorApplication.OpenScene(current); } if (EditorUtility.DisplayDialog("TextScene/built-in mixed usage", "It is not recommended to mix TextScene usage with built-in Unity scenes. This may cause the TextScene system to miss updates or simply behave totally weird! If you plan on using the TextScene system, you should save the current scene via the TextScene menu item and - if successfully saved (please inspect the log for errors and warnings) - remove the original from the Assets folder. Please note that not all components/Unity objects can be saved into the TextScene format, so don't delete the original until you are 100% sure you saved what you need!", "Save to TextScene now!", "I know what I'm doing")) { TextSceneSerializer.SaveCurrent(); } else { alarmingEditorScene = EditorApplication.currentScene; currentScene = ""; } } } //Regular checks to see if the scene file was edited since our last load. if (currentScene.Length > 0 && EditorApplication.timeSinceStartup > nextCheckForChangedFile) { if (File.Exists(currentScene)) { DateTime lastWriteTime = File.GetLastWriteTime(currentScene); if (lastWriteTime > currentSceneLoaded) { int result = EditorUtility.DisplayDialogComplex("Scene changed", "The TextScene you currently have open changed (" + lastWriteTime + "). Do you want to reload it?", "Yes", "Backup mine first", "No"); if (result == 0) //Yes { TextSceneDeserializer.Load(currentScene); } else if (result == 1)//Backup first { string filename = EditorUtility.SaveFilePanel("Backup TextScene", currentScene.Substring(0, currentScene.LastIndexOf('/')), "backup", "txt"); if (filename.Length != 0) { //This is overwritten during the save. string toLoad = currentScene; TextSceneSerializer.Save(filename); TextSceneDeserializer.Load(toLoad); } else { EditorUtility.DisplayDialog("Unsaved", "You chose to cancel the backup of your own scene file. It is recommended that you manually save a copy, and merge with the updated file from disk (" + currentScene + ")", "OK"); } } else//No { //HACK: Shut this message up. We don't want to get asked this again until the // file changes again. currentSceneLoaded = DateTime.Now; } } } else { if (EditorUtility.DisplayDialog("TextScene file gone!", "It seems like the TextScene representation of your open file has been deleted. Do you want to re-save it (" + currentScene + ")?", "Yes", "No")) { TextSceneSerializer.Save(currentScene); } else { currentScene = ""; } } //Also check for changed temp files (.unity in TempScenes). This happens if //the user uses the built-in save functionality. CheckForChangedTemp(); nextCheckForChangedFile = EditorApplication.timeSinceStartup + 1.0f; } }