/// <summary> /// Set the active save slot /// </summary> /// <param name="slot"> Target save slot </param> /// <param name="notifyListeners"> Send a message to all saveables to load the new save file </param> public static void SetSlot(int slot, bool notifyListeners, SaveGame saveGame = null) { // if (activeSlot == slot && saveGame == null) // { // Debug.LogWarning("Already loaded this slot."); // return; // } // Ensure the current game is saved, and write it to disk, if that is wanted behaviour. if (SaveSettings.Get().autoSaveOnSlotSwitch&& activeSaveGame != null) { WriteActiveSaveToDisk(); } if (slot < 0 || slot > SaveSettings.Get().maxSaveSlotCount) { Debug.LogWarning("SaveMaster: Attempted to set illegal slot."); return; } activeSlot = slot; activeSaveGame = (saveGame == null) ? SaveFileUtility.LoadSave(slot, true) : saveGame; if (notifyListeners) { SyncLoad(); } PlayerPrefs.SetInt("SM-LastUsedSlot", slot); }
private void Awake() { if (this == instance) { Debug.LogWarning("Duplicate save master found. " + "Ensure that the save master has not been added anywhere in your scene."); GameObject.Destroy(this.gameObject); return; } var settings = SaveSettings.Get(); if (settings.loadDefaultSlotOnStart) { SetSlot(settings.defaultSlot, true); } if (settings.trackTimePlayed) { StartCoroutine(IncrementTimePlayed()); } if (settings.useHotkeys) { StartCoroutine(TrackHotkeyUsage()); } }
public static void OpenSaveLocation() { string path = string.Format("{0}/{1}", Application.persistentDataPath, SaveSettings.Get().fileFolderName); #if UNITY_EDITOR_WIN Directory.CreateDirectory(path); string winPath = path.Replace(@"/", @"\"); // explorer doesn't like front slashes System.Diagnostics.Process.Start("explorer.exe", "/open," + winPath); #elif UNITY_EDITOR_OSX string macPath = path.Replace("\\", "/"); // mac finder doesn't like backward slashes bool openInsidesOfFolder = false; if (System.IO.Directory.Exists(macPath)) // if path requested is a folder, automatically open insides of that folder { openInsidesOfFolder = true; } if (!macPath.StartsWith("\"")) { macPath = "\"" + macPath; } if (!macPath.EndsWith("\"")) { macPath = macPath + "\""; } string arguments = (openInsidesOfFolder ? "" : "-R ") + macPath; System.Diagnostics.Process.Start("open", arguments); #endif }
public string OnSave() { if (changesMade > 0) { changesMade = 0; int c = spawnInfo.Count; SaveData data = new SaveData() { infoCollection = new SpawnInfo[c], spawnCountHistory = this.spawnCountHistory }; int i = 0; foreach (SpawnInfo item in spawnInfo.Values) { data.infoCollection[i] = item; i++; } return(JsonUtility.ToJson(data, SaveSettings.Get().useJsonPrettyPrint)); } else { return(""); } }
// This will get called on android devices when they leave the game private void OnApplicationPause(bool pause) { if (!SaveSettings.Get().autoSaveOnExit) { return; } WriteActiveSaveToDisk(); }
private void OnApplicationQuit() { if (!SaveSettings.Get().autoSaveOnExit) { return; } isQuittingGame = true; WriteActiveSaveToDisk(); }
private IEnumerator AutoSaveGame() { WaitForSeconds wait = new WaitForSeconds(SaveSettings.Get().saveIntervalTime); while (true) { yield return(wait); WriteActiveSaveToDisk(); } }
private IEnumerator TrackHotkeyUsage() { var settings = SaveSettings.Get(); while (true) { yield return(null); if (!settings.useHotkeys) { continue; } if (Input.GetKeyDown(settings.wipeActiveSceneData)) { SaveMaster.WipeSceneData(SceneManager.GetActiveScene().name); } if (Input.GetKeyDown(settings.saveAndWriteToDiskKey)) { var stopWatch = new System.Diagnostics.Stopwatch(); stopWatch.Start(); WriteActiveSaveToDisk(); stopWatch.Stop(); Debug.Log(string.Format("Synced objects & Witten game to disk. MS: {0}", stopWatch.ElapsedMilliseconds.ToString())); } if (Input.GetKeyDown(settings.syncSaveGameKey)) { var stopWatch = new System.Diagnostics.Stopwatch(); stopWatch.Start(); SyncSave(); stopWatch.Stop(); Debug.Log(string.Format("Synced (Save) objects. MS: {0}", stopWatch.ElapsedMilliseconds.ToString())); } if (Input.GetKeyDown(settings.syncLoadGameKey)) { var stopWatch = new System.Diagnostics.Stopwatch(); stopWatch.Start(); SyncLoad(); stopWatch.Stop(); Debug.Log(string.Format("Synced (Load) objects. MS: {0}", stopWatch.ElapsedMilliseconds.ToString())); } } }
/// <summary> /// Returns unique id for specified saveable component. /// </summary> /// <param name="saveableComponent"></param> /// <returns></returns> private string GenerateIdForSaveableComponent(ISaveableComponent saveableComponent) { var identifier = GetBaseIdForSaveableComponent(saveableComponent); while (!IsIdentifierUnique(identifier)) { int guidLength = SaveSettings.Get().componentGuidLength; string guidString = Guid.NewGuid().ToString().Substring(0, guidLength); identifier = string.Format("{0}-{1}", identifier, guidString); } return(identifier); }
public static int GetAvailableSaveSlot() { int slotCount = SaveSettings.Get().maxSaveSlotCount; for (int i = 0; i < slotCount; i++) { if (!ObtainSavePaths().ContainsKey(i)) { return(i); } } return(-1); }
/// <summary> /// Set the active save slot. (Do note: If you don't want to auto save on slot switch, you can change this in the save setttings) /// </summary> /// <param name="slot"> Target save slot </param> /// <param name="reloadSaveables"> Send a message to all saveables to load the new save file </param> public static void SetSlot(int slot, bool reloadSaveables, SaveGame saveGame = null) { if (activeSlot == slot && saveGame == null) { Debug.LogWarning("Already loaded this slot."); return; } // Ensure the current game is saved, and write it to disk, if that is wanted behaviour. if (SaveSettings.Get().autoSaveOnSlotSwitch&& activeSaveGame != null) { WriteActiveSaveToDisk(); } if (SaveSettings.Get().cleanSavedPrefabsOnSlotSwitch) { ClearActiveSavedPrefabs(); } if (slot < 0 || slot > SaveSettings.Get().maxSaveSlotCount) { Debug.LogWarning("SaveMaster: Attempted to set illegal slot."); return; } OnSlotChangeBegin.Invoke(slot); activeSlot = slot; activeSaveGame = (saveGame == null) ? SaveFileUtility.LoadSave(slot, true) : saveGame; if (reloadSaveables) { SyncLoad(); } SyncReset(); PlayerPrefs.SetInt("SM-LastUsedSlot", slot); OnSlotChangeDone.Invoke(slot); }
public string OnSave() { isDirty = false; int c = spawnInfo.Count; SaveData data = new SaveData() { infoCollection = new SpawnInfo[c] }; int i = 0; foreach (SpawnInfo item in spawnInfo.Values) { data.infoCollection[i] = item; i++; } return(JsonUtility.ToJson(data, SaveSettings.Get().useJsonPrettyPrint)); }
public static void WriteSave(SaveGame saveGame, int saveSlot) { string savePath = string.Format("{0}/{1}{2}{3}", DataPath, gameFileName, saveSlot.ToString(), fileExtentionName); if (!cachedSavePaths.ContainsKey(saveSlot)) { cachedSavePaths.Add(saveSlot, savePath); } Log(string.Format("Saving game slot {0} to : {1}", saveSlot.ToString(), savePath)); saveGame.OnWrite(); using (var writer = new BinaryWriter(File.Open(savePath, FileMode.Create))) { var jsonString = JsonUtility.ToJson(saveGame, SaveSettings.Get().useJsonPrettyPrint); writer.Write(jsonString); } #if UNITY_WEBGL && !UNITY_EDITOR SyncFiles(); #endif }
public static void OpenSaveSystemSettings() { Selection.activeInstanceID = SaveSettings.Get().GetInstanceID(); }
public static void OpenSaveLocation() { string dataPath = string.Format("{0}/{1}/", Application.persistentDataPath, SaveSettings.Get().fileFolderName); #if UNITY_EDITOR_WIN dataPath = dataPath.Replace(@"/", @"\"); // Windows uses backward slashes #elif UNITY_EDITOR_OSX || UNITY_EDITOR_LINUX dataPath = dataPath.Replace("\\", "/"); // Linux and MacOS use forward slashes #endif if (!Directory.Exists(dataPath)) { Directory.CreateDirectory(dataPath); } EditorUtility.RevealInFinder(dataPath); }
public void OnValidate() { if (Application.isPlaying) { return; } bool isPrefab; #if UNITY_2018_3_OR_NEWER isPrefab = UnityEditor.PrefabUtility.IsPartOfPrefabAsset(this.gameObject); #else isPrefab = this.gameObject.scene.name == null; #endif // Set a new save identification if it is not a prefab at the moment. if (!isPrefab) { Lowscope.Tools.ValidateHierarchy.Add(this); bool isDuplicate = false; Saveable saveable = null; if (sceneName != gameObject.scene.name) { UnityEditor.Undo.RecordObject(this, "Updated Object Scene ID"); if (SaveSettings.Get().resetSaveableIdOnNewScene) { saveIdentification = ""; } sceneName = gameObject.scene.name; } if (SaveSettings.Get().resetSaveableIdOnDuplicate) { // Does the object have a valid save id? If not, we give a new one. if (!string.IsNullOrEmpty(saveIdentification)) { isDuplicate = saveIdentificationCache.TryGetValue(saveIdentification, out saveable); if (!isDuplicate) { if (saveIdentification != "") { saveIdentificationCache.Add(saveIdentification, this); } } else { if (saveable == null) { saveIdentificationCache.Remove(saveIdentification); saveIdentificationCache.Add(saveIdentification, this); } else { if (saveable.gameObject != this.gameObject) { UnityEditor.Undo.RecordObject(this, "Updated Object Scene ID"); saveIdentification = ""; } } } } } if (string.IsNullOrEmpty(saveIdentification)) { UnityEditor.Undo.RecordObject(this, "ClearedSaveIdentification"); int guidLength = SaveSettings.Get().gameObjectGuidLength; #if NET_4_6 saveIdentification = $"{gameObject.scene.name}-{gameObject.name}-{System.Guid.NewGuid().ToString().Substring(0, 5)}"; #else saveIdentification = string.Format("{0}-{1}-{2}", gameObject.scene.name, gameObject.name, System.Guid.NewGuid().ToString().Substring(0, guidLength)); #endif saveIdentificationCache.Add(saveIdentification, this); UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(this.gameObject.scene); } } else { saveIdentification = string.Empty; sceneName = string.Empty; } List <ISaveable> obtainSaveables = new List <ISaveable>(); obtainSaveables.AddRange(GetComponentsInChildren <ISaveable>(true).ToList()); for (int i = 0; i < externalListeners.Count; i++) { if (externalListeners[i] != null) { obtainSaveables.AddRange(externalListeners[i].GetComponentsInChildren <ISaveable>(true).ToList()); } } for (int i = cachedSaveableComponents.Count - 1; i >= 0; i--) { if (cachedSaveableComponents[i].monoBehaviour == null) { cachedSaveableComponents.RemoveAt(i); } } if (obtainSaveables.Count != cachedSaveableComponents.Count) { if (cachedSaveableComponents.Count > obtainSaveables.Count) { for (int i = cachedSaveableComponents.Count - 1; i >= obtainSaveables.Count; i--) { cachedSaveableComponents.RemoveAt(i); } } int saveableComponentCount = cachedSaveableComponents.Count; for (int i = saveableComponentCount - 1; i >= 0; i--) { if (cachedSaveableComponents[i] == null) { cachedSaveableComponents.RemoveAt(i); } } ISaveable[] cachedSaveables = new ISaveable[cachedSaveableComponents.Count]; for (int i = 0; i < cachedSaveables.Length; i++) { cachedSaveables[i] = cachedSaveableComponents[i].monoBehaviour as ISaveable; } ISaveable[] missingElements = obtainSaveables.Except(cachedSaveables).ToArray(); for (int i = 0; i < missingElements.Length; i++) { CachedSaveableComponent newSaveableComponent = new CachedSaveableComponent() { monoBehaviour = missingElements[i] as MonoBehaviour }; string typeString = newSaveableComponent.monoBehaviour.GetType().Name.ToString(); var identifier = ""; while (!IsIdentifierUnique(identifier)) { int guidLength = SaveSettings.Get().componentGuidLength; string guidString = System.Guid.NewGuid().ToString().Substring(0, guidLength); identifier = string.Format("{0}-{1}", typeString, guidString); } newSaveableComponent.identifier = identifier; cachedSaveableComponents.Add(newSaveableComponent); } UnityEditor.EditorUtility.SetDirty(this); UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(this.gameObject.scene); } }