From 6e860053f58370862819a50c5830c3321af9a297 Mon Sep 17 00:00:00 2001 From: Christopher Date: Wed, 30 Nov 2016 11:27:22 +0000 Subject: [PATCH] Simplified save system to not use slots. A full history of save points is stored, and user can rewind to previous save points. --- Assets/Fungus/Scripts/Commands/LoadGame.cs | 36 - Assets/Fungus/Scripts/Commands/SavePoint.cs | 17 +- Assets/Fungus/Scripts/Components/GameSaver.cs | 31 - .../Scripts/Components/SaveGameHelper.cs | 61 + ...meSaver.cs.meta => SaveGameHelper.cs.meta} | 0 .../Fungus/Scripts/Components/SaveManager.cs | 106 +- .../Scripts/SavePoints/SaveGameObjects.cs | 17 + .../SavePoints/SaveGameObjects.cs.meta} | 4 +- .../Fungus/Scripts/SavePoints/SaveHistory.cs | 58 + .../SaveHistory.cs.meta} | 4 +- .../Scripts/SavePoints/SavePointData.cs | 47 +- Assets/Fungus/Scripts/Signals/SaveSignals.cs | 23 + .../Scripts/Signals/SaveSignals.cs.meta | 12 + Assets/FungusExamples/SaveGame/Menu.unity | 31 +- .../FungusExamples/SaveGame/SaveExample.unity | 2441 +++++++++++++++++ .../SaveGame/SaveExample.unity.meta | 8 + Assets/FungusExamples/SaveGame/SavePicker.cs | 34 - Assets/FungusExamples/SaveGame/SceneA.unity | 5 +- ProjectSettings/ProjectSettings.asset | 3 + 19 files changed, 2713 insertions(+), 225 deletions(-) delete mode 100644 Assets/Fungus/Scripts/Commands/LoadGame.cs delete mode 100644 Assets/Fungus/Scripts/Components/GameSaver.cs create mode 100644 Assets/Fungus/Scripts/Components/SaveGameHelper.cs rename Assets/Fungus/Scripts/Components/{GameSaver.cs.meta => SaveGameHelper.cs.meta} (100%) create mode 100644 Assets/Fungus/Scripts/SavePoints/SaveGameObjects.cs rename Assets/{FungusExamples/SaveGame/SavePicker.cs.meta => Fungus/Scripts/SavePoints/SaveGameObjects.cs.meta} (76%) create mode 100644 Assets/Fungus/Scripts/SavePoints/SaveHistory.cs rename Assets/Fungus/Scripts/{Commands/LoadGame.cs.meta => SavePoints/SaveHistory.cs.meta} (76%) create mode 100644 Assets/Fungus/Scripts/Signals/SaveSignals.cs create mode 100644 Assets/Fungus/Scripts/Signals/SaveSignals.cs.meta create mode 100644 Assets/FungusExamples/SaveGame/SaveExample.unity create mode 100644 Assets/FungusExamples/SaveGame/SaveExample.unity.meta delete mode 100644 Assets/FungusExamples/SaveGame/SavePicker.cs diff --git a/Assets/Fungus/Scripts/Commands/LoadGame.cs b/Assets/Fungus/Scripts/Commands/LoadGame.cs deleted file mode 100644 index ed661912..00000000 --- a/Assets/Fungus/Scripts/Commands/LoadGame.cs +++ /dev/null @@ -1,36 +0,0 @@ -// This code is part of the Fungus library (http://fungusgames.com) maintained by Chris Gregan (http://twitter.com/gofungus). -// It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE) - -using UnityEngine; - -namespace Fungus -{ - [CommandInfo("Variable", - "Load Game", - "Loads a previously saved game. The original scene is loaded and the resume block is executed.")] - public class LoadGame : Command - { - [SerializeField] protected IntegerData saveSlot = new IntegerData(0); - - #region Public members - - public override void OnEnter() - { - var saveManager = FungusManager.Instance.SaveManager; - - saveManager.Load(saveSlot.Value); - } - - public override string GetSummary() - { - return saveSlot.Value.ToString(); - } - - public override Color GetButtonColor() - { - return new Color32(235, 191, 217, 255); - } - - #endregion - } -} \ No newline at end of file diff --git a/Assets/Fungus/Scripts/Commands/SavePoint.cs b/Assets/Fungus/Scripts/Commands/SavePoint.cs index 085a7684..640d4c76 100644 --- a/Assets/Fungus/Scripts/Commands/SavePoint.cs +++ b/Assets/Fungus/Scripts/Commands/SavePoint.cs @@ -14,29 +14,28 @@ namespace Fungus { [SerializeField] protected string saveKey; - [SerializeField] protected string description; + [SerializeField] protected string saveDescription; - [SerializeField] protected bool saveNow; + [SerializeField] protected bool resumeFromHere = true; #region Public members + public string SaveKey { get { return saveKey; } } + + public bool ResumeFromHere { get { return resumeFromHere; } } + public override void OnEnter() { var saveManager = FungusManager.Instance.SaveManager; - saveManager.PopulateSaveBuffer(saveKey, description); - - if (saveNow) - { - saveManager.Save(); - } + saveManager.AddSavePoint(saveKey, saveDescription); Continue(); } public override string GetSummary() { - return saveKey; + return saveKey + " : " + saveDescription; } public override Color GetButtonColor() diff --git a/Assets/Fungus/Scripts/Components/GameSaver.cs b/Assets/Fungus/Scripts/Components/GameSaver.cs deleted file mode 100644 index f2176c71..00000000 --- a/Assets/Fungus/Scripts/Components/GameSaver.cs +++ /dev/null @@ -1,31 +0,0 @@ -using UnityEngine; -using System.Collections; -using System.Collections.Generic; -using UnityEngine.SceneManagement; - -namespace Fungus -{ - public class GameSaver : MonoBehaviour - { - [SerializeField] protected string startScene = ""; - - [SerializeField] protected List flowcharts = new List(); - - #region Public methods - - public List Flowcharts { get { return flowcharts; } } - - public virtual void Save() - { - var saveManager = FungusManager.Instance.SaveManager; - saveManager.Save(); - } - - public virtual void LoadScene(string sceneName) - { - SceneManager.LoadScene(sceneName); - } - - #endregion - } -} \ No newline at end of file diff --git a/Assets/Fungus/Scripts/Components/SaveGameHelper.cs b/Assets/Fungus/Scripts/Components/SaveGameHelper.cs new file mode 100644 index 00000000..899e13ef --- /dev/null +++ b/Assets/Fungus/Scripts/Components/SaveGameHelper.cs @@ -0,0 +1,61 @@ +using UnityEngine; +using UnityEngine.UI; +using System.Collections; +using System.Collections.Generic; +using UnityEngine.SceneManagement; + +namespace Fungus +{ + public class SaveGameHelper : MonoBehaviour + { + [SerializeField] protected string startScene = ""; + + [SerializeField] protected SaveGameObjects saveGameObjects = new SaveGameObjects(); + + protected virtual void OnEnable() + { + SaveSignals.OnGameSave += OnGameSave; + } + + protected virtual void OnDisable() + { + SaveSignals.OnGameSave -= OnGameSave; + } + + protected virtual void OnGameSave(string saveKey, string saveDescription) + { + // TODO: Play sound effect + } + + #region Public methods + + public SaveGameObjects SaveGameObjects { get { return saveGameObjects; } } + + public virtual void Save() + { + var saveManager = FungusManager.Instance.SaveManager; + saveManager.Save(); + } + + public virtual void Load() + { + var saveManager = FungusManager.Instance.SaveManager; + saveManager.Load(); + } + + public virtual void Rewind() + { + var saveManager = FungusManager.Instance.SaveManager; + saveManager.Rewind(); + } + + public virtual void Restart() + { + var saveManager = FungusManager.Instance.SaveManager; + saveManager.Clear(); + SceneManager.LoadScene(startScene); + } + + #endregion + } +} \ No newline at end of file diff --git a/Assets/Fungus/Scripts/Components/GameSaver.cs.meta b/Assets/Fungus/Scripts/Components/SaveGameHelper.cs.meta similarity index 100% rename from Assets/Fungus/Scripts/Components/GameSaver.cs.meta rename to Assets/Fungus/Scripts/Components/SaveGameHelper.cs.meta diff --git a/Assets/Fungus/Scripts/Components/SaveManager.cs b/Assets/Fungus/Scripts/Components/SaveManager.cs index 0b13c414..e111d89e 100644 --- a/Assets/Fungus/Scripts/Components/SaveManager.cs +++ b/Assets/Fungus/Scripts/Components/SaveManager.cs @@ -5,112 +5,66 @@ namespace Fungus { public class SaveManager : MonoBehaviour { - const string ActiveSlotKey = "active_slot"; + const string DefaultSaveDataKey = "save_data"; - const string SlotKeyFormat = "slot{0}"; + protected static SaveHistory saveHistory = new SaveHistory(); - protected string saveBuffer = ""; - - protected virtual string FormatSaveKey(int slot) - { - return string.Format(SlotKeyFormat, slot); - } - - protected virtual void StoreJSONData(string key, string jsonData) + protected virtual void ReadSaveHistory(string saveDataKey) { - if (key.Length > 0) + var historyData = PlayerPrefs.GetString(saveDataKey); + if (!string.IsNullOrEmpty(historyData)) { - PlayerPrefs.SetString(key, jsonData); + var tempSaveHistory = JsonUtility.FromJson(historyData); + if (tempSaveHistory != null) + { + saveHistory = tempSaveHistory; + } } } - protected virtual string LoadJSONData(string key) + protected virtual void WriteSaveHistory(string saveDataKey) { - if (key.Length > 0) + var historyData = JsonUtility.ToJson(saveHistory, true); + if (!string.IsNullOrEmpty(historyData)) { - return PlayerPrefs.GetString(key); + PlayerPrefs.SetString(saveDataKey, historyData); + PlayerPrefs.Save(); } - - return ""; } #region Public members - public virtual int ActiveSlot + public virtual void Save(string saveDataKey = DefaultSaveDataKey) { - get - { - return PlayerPrefs.GetInt(ActiveSlotKey); - } - set - { - PlayerPrefs.SetInt(ActiveSlotKey, value); - } + WriteSaveHistory(saveDataKey); } - - public virtual void Save() + + public void Load(string saveDataKey = DefaultSaveDataKey) { - if (saveBuffer == "") + ReadSaveHistory(saveDataKey); + if (saveHistory != null) { - // Nothing to save - return; + saveHistory.LoadLatestSavePoint(); } - - var key = FormatSaveKey(ActiveSlot); - - PlayerPrefs.SetString(key, saveBuffer); - - saveBuffer = ""; } - public virtual bool SlotExists(int slot) + public virtual void AddSavePoint(string saveKey, string saveDescription) { - var key = FormatSaveKey(slot); - - if (PlayerPrefs.HasKey(key) && - PlayerPrefs.GetString(key) != "") - { - return false; - } - - return true; + saveHistory.AddSavePoint(saveKey, saveDescription); } - public virtual void Load(int slot) + public virtual void Rewind() { - ActiveSlot = slot; - - var key = FormatSaveKey(slot); - - var saveDataJSON = LoadJSONData(key); - if (saveDataJSON != "") + if (saveHistory.NumSavePoints > 0) { - SavePointData.Decode(saveDataJSON); + saveHistory.RemoveSavePoint(); + saveHistory.LoadLatestSavePoint(); } } - public virtual void LoadNewGame(int slot, string saveDescription) - { - var key = FormatSaveKey(slot); - - var saveDataJSON = SavePointData.EncodeNewGame(saveDescription, SceneManager.GetActiveScene().name); - - // Create a new save entry - PlayerPrefs.SetString(key, saveDataJSON); - - SavePointLoaded.NotifyEventHandlers("new_game"); - } - - public virtual void Delete(int slot) - { - var key = FormatSaveKey(slot); - PlayerPrefs.DeleteKey(key); - } - - public virtual void PopulateSaveBuffer(string saveKey, string description) + public virtual void Clear() { - saveBuffer = SavePointData.Encode(saveKey, description, SceneManager.GetActiveScene().name); - Debug.Log(saveBuffer); + saveHistory.Clear(); } #endregion diff --git a/Assets/Fungus/Scripts/SavePoints/SaveGameObjects.cs b/Assets/Fungus/Scripts/SavePoints/SaveGameObjects.cs new file mode 100644 index 00000000..e9eeb4f4 --- /dev/null +++ b/Assets/Fungus/Scripts/SavePoints/SaveGameObjects.cs @@ -0,0 +1,17 @@ +using UnityEngine; +using System.Collections.Generic; + +namespace Fungus +{ + [System.Serializable] + public class SaveGameObjects + { + [SerializeField] protected List flowcharts = new List(); + + #region Public methods + + public List Flowcharts { get { return flowcharts; } } + + #endregion + } +} \ No newline at end of file diff --git a/Assets/FungusExamples/SaveGame/SavePicker.cs.meta b/Assets/Fungus/Scripts/SavePoints/SaveGameObjects.cs.meta similarity index 76% rename from Assets/FungusExamples/SaveGame/SavePicker.cs.meta rename to Assets/Fungus/Scripts/SavePoints/SaveGameObjects.cs.meta index 017e35e8..293553be 100644 --- a/Assets/FungusExamples/SaveGame/SavePicker.cs.meta +++ b/Assets/Fungus/Scripts/SavePoints/SaveGameObjects.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 60a19f3f0e9b84b14b2b310a296de1b1 -timeCreated: 1479485750 +guid: f9c00b58b03474e37b54a4b39ed6c8ee +timeCreated: 1480503989 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/Assets/Fungus/Scripts/SavePoints/SaveHistory.cs b/Assets/Fungus/Scripts/SavePoints/SaveHistory.cs new file mode 100644 index 00000000..c6dd749f --- /dev/null +++ b/Assets/Fungus/Scripts/SavePoints/SaveHistory.cs @@ -0,0 +1,58 @@ +using UnityEngine; +using System.Collections.Generic; +using Fungus; +using UnityEngine.SceneManagement; + +namespace Fungus +{ + [System.Serializable] + public class SaveHistory + { + /// + /// Version number of current save data format. + /// + protected const int SaveDataVersion = 1; + + [SerializeField] protected int version = SaveDataVersion; + + [SerializeField] protected List savePoints = new List(); + + #region Public methods + + public int NumSavePoints { get { return savePoints.Count; } } + + public void AddSavePoint(string saveKey, string saveDescription) + { + string sceneName = SceneManager.GetActiveScene().name; + var savePointData = SavePointData.Encode(saveKey, saveDescription, sceneName); + savePoints.Add(savePointData); + } + + /// + /// Removes the latest save point. + /// + public void RemoveSavePoint() + { + if (savePoints.Count > 0) + { + savePoints.RemoveAt(savePoints.Count - 1); + } + } + + public void LoadLatestSavePoint() + { + if (savePoints.Count > 0) + { + var savePointData = savePoints[savePoints.Count - 1]; + SavePointData.Decode(savePointData); + } + } + + public void Clear() + { + savePoints.Clear(); + } + + #endregion + } +} diff --git a/Assets/Fungus/Scripts/Commands/LoadGame.cs.meta b/Assets/Fungus/Scripts/SavePoints/SaveHistory.cs.meta similarity index 76% rename from Assets/Fungus/Scripts/Commands/LoadGame.cs.meta rename to Assets/Fungus/Scripts/SavePoints/SaveHistory.cs.meta index 65916a89..05ceb899 100644 --- a/Assets/Fungus/Scripts/Commands/LoadGame.cs.meta +++ b/Assets/Fungus/Scripts/SavePoints/SaveHistory.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 4bd5b7f5cc3944217aa05a6fa8552baf -timeCreated: 1478530280 +guid: fd859426b9f7445b5a1d7281f4943bb8 +timeCreated: 1480422606 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/Assets/Fungus/Scripts/SavePoints/SavePointData.cs b/Assets/Fungus/Scripts/SavePoints/SavePointData.cs index 5ad74b63..7617f57f 100644 --- a/Assets/Fungus/Scripts/SavePoints/SavePointData.cs +++ b/Assets/Fungus/Scripts/SavePoints/SavePointData.cs @@ -7,12 +7,6 @@ namespace Fungus [System.Serializable] public class SavePointData { - /// - /// Version number of current save data format. - /// - protected const int SavePointDataVersion = 0; - - [SerializeField] protected int version; [SerializeField] protected string saveKey; [SerializeField] protected string description; [SerializeField] protected string sceneName; @@ -36,19 +30,37 @@ namespace Fungus FlowchartData.Decode(flowchartData); } - SavePointLoaded.NotifyEventHandlers(savePointData.saveKey); - - ExecuteBlocks(savePointData); + ExecuteBlocks(savePointData.saveKey); } - protected static void ExecuteBlocks(SavePointData savePointData) + protected static void ExecuteBlocks(string saveKey) { + SavePointLoaded.NotifyEventHandlers(saveKey); + + // Execute any block containing a SavePoint command matching the save key, with Resume From Here enabled + var savePoints = Object.FindObjectsOfType(); + for (int i = 0; i < savePoints.Length; i++) + { + var savePoint = savePoints[i]; + if (savePoint.ResumeFromHere && + string.Compare(savePoint.SaveKey, saveKey, true) == 0) + { + int index = savePoint.CommandIndex; + var block = savePoint.ParentBlock; + var flowchart = savePoint.GetFlowchart(); + flowchart.ExecuteBlock(block, index + 1); + + // Assume there's only one SavePoint using this key + break; + } + } + // Execute any block containing a Label matching the save key var labels = Object.FindObjectsOfType