diff --git a/Assets/Fungus/Scripts/Commands/SavePoint.cs b/Assets/Fungus/Scripts/Commands/SavePoint.cs
index b3dfcc39..e2d4a45f 100644
--- a/Assets/Fungus/Scripts/Commands/SavePoint.cs
+++ b/Assets/Fungus/Scripts/Commands/SavePoint.cs
@@ -2,8 +2,6 @@
// It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE)
using UnityEngine;
-using System.Collections;
-using UnityEngine.SceneManagement;
namespace Fungus
{
diff --git a/Assets/Fungus/Scripts/Components/SaveData.cs b/Assets/Fungus/Scripts/Components/SaveData.cs
index 750748c7..280b8651 100644
--- a/Assets/Fungus/Scripts/Components/SaveData.cs
+++ b/Assets/Fungus/Scripts/Components/SaveData.cs
@@ -4,38 +4,60 @@ using System.Collections.Generic;
namespace Fungus
{
///
- /// Contains a list of game objects whose state will be saved for each Save Point.
+ /// This component encodes and decodes a list of game objects to be saved for each Save Point.
+ /// It knows how to encode / decode concrete game classes like Flowchart and FlowchartData.
+ /// To extend the save system to handle other data types, just modify or subclass this component.
///
public class SaveData : MonoBehaviour
{
+ protected const string FlowchartDataKey = "FlowchartData";
+
[Tooltip("A list of Flowchart objects whose variables will be encoded in the save data. Boolean, Integer, Float and String variables are supported.")]
[SerializeField] protected List flowcharts = new List();
#region Public methods
///
- /// Encodes the list of Flowcharts and adds it to a Save Point Data object.
- ///
- public void Encode(SavePointData savePointData)
+ /// Encodes the objects to be saved as a list of SaveDataItems.
+ /// saveDataItems)
{
for (int i = 0; i < flowcharts.Count; i++)
{
var flowchart = flowcharts[i];
var flowchartData = FlowchartData.Encode(flowchart);
- savePointData.FlowchartDatas.Add(flowchartData);
+
+ var saveDataItem = SaveDataItem.Create(FlowchartDataKey, JsonUtility.ToJson(flowchartData));
+
+ saveDataItems.Add(saveDataItem);
}
}
///
- /// Decodes the Flowchart data from the save point data.
+ /// Decodes the loaded list of SaveDataItems to restore the saved game state.
///
- public void Decode(SavePointData savePointData)
+ public virtual void Decode(List saveDataItems)
{
- for (int i = 0; i < savePointData.FlowchartDatas.Count; i++)
+ for (int i = 0; i < saveDataItems.Count; i++)
{
- var flowchartData = savePointData.FlowchartDatas[i];
- FlowchartData.Decode(flowchartData);
- }
+ var saveDataItem = saveDataItems[i];
+ if (saveDataItem == null)
+ {
+ continue;
+ }
+
+ if (saveDataItem.DataType == FlowchartDataKey)
+ {
+ var flowchartData = JsonUtility.FromJson(saveDataItem.Data);
+ if (flowchartData == null)
+ {
+ Debug.LogError("Failed to decode Flowchart save data item");
+ return;
+ }
+
+ FlowchartData.Decode(flowchartData);
+ }
+ }
}
#endregion
diff --git a/Assets/Fungus/Scripts/Components/SaveManager.cs b/Assets/Fungus/Scripts/Components/SaveManager.cs
index b47734bc..41fafe76 100644
--- a/Assets/Fungus/Scripts/Components/SaveManager.cs
+++ b/Assets/Fungus/Scripts/Components/SaveManager.cs
@@ -1,5 +1,7 @@
-using UnityEngine;
-using System.Collections;
+// 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;
using UnityEngine.SceneManagement;
namespace Fungus
diff --git a/Assets/Fungus/Scripts/Editor/SaveData.cs b/Assets/Fungus/Scripts/Editor/SaveDataEditor.cs
similarity index 100%
rename from Assets/Fungus/Scripts/Editor/SaveData.cs
rename to Assets/Fungus/Scripts/Editor/SaveDataEditor.cs
diff --git a/Assets/Fungus/Scripts/Editor/SaveData.cs.meta b/Assets/Fungus/Scripts/Editor/SaveDataEditor.cs.meta
similarity index 100%
rename from Assets/Fungus/Scripts/Editor/SaveData.cs.meta
rename to Assets/Fungus/Scripts/Editor/SaveDataEditor.cs.meta
diff --git a/Assets/Fungus/Scripts/Utils/FlowchartData.cs b/Assets/Fungus/Scripts/Utils/FlowchartData.cs
index 25bc493c..d1fe8485 100644
--- a/Assets/Fungus/Scripts/Utils/FlowchartData.cs
+++ b/Assets/Fungus/Scripts/Utils/FlowchartData.cs
@@ -1,4 +1,7 @@
-using System.Collections.Generic;
+// 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 System.Collections.Generic;
using UnityEngine;
namespace Fungus
diff --git a/Assets/Fungus/Scripts/Utils/SaveDataItem.cs b/Assets/Fungus/Scripts/Utils/SaveDataItem.cs
new file mode 100644
index 00000000..16bb0368
--- /dev/null
+++ b/Assets/Fungus/Scripts/Utils/SaveDataItem.cs
@@ -0,0 +1,45 @@
+// 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
+{
+ ///
+ /// A container for a single unity of saved data.
+ /// The data and its associated type are stored as string properties.
+ /// The data would typically be a JSON string representing a saved object.
+ ///
+ [System.Serializable]
+ public class SaveDataItem
+ {
+ [SerializeField] protected string dataType = "";
+ [SerializeField] protected string data = "";
+
+ #region Public methods
+
+ ///
+ /// Gets the type of the data.
+ ///
+ public virtual string DataType { get { return dataType; } }
+
+ ///
+ /// Gets the data.
+ ///
+ public virtual string Data { get { return data; } }
+
+ ///
+ /// Factory method to create a new SaveDataItem.
+ ///
+ public static SaveDataItem Create(string dataType, string data)
+ {
+ var item = new SaveDataItem();
+ item.dataType = dataType;
+ item.data = data;
+
+ return item;
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/Assets/Fungus/Scripts/Utils/SaveDataItem.cs.meta b/Assets/Fungus/Scripts/Utils/SaveDataItem.cs.meta
new file mode 100644
index 00000000..a9c855e9
--- /dev/null
+++ b/Assets/Fungus/Scripts/Utils/SaveDataItem.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 67dfa5e8ded9244f98136428ed129403
+timeCreated: 1484649086
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Fungus/Scripts/Utils/SavePointData.cs b/Assets/Fungus/Scripts/Utils/SavePointData.cs
index 7e811a59..fec9d927 100644
--- a/Assets/Fungus/Scripts/Utils/SavePointData.cs
+++ b/Assets/Fungus/Scripts/Utils/SavePointData.cs
@@ -1,43 +1,25 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
-using System.Collections;
+using UnityEngine.Events;
namespace Fungus
{
///
- /// Serializable container for a Save Point.
+ /// Serializable container for a Save Point's data.
+ /// All data is stored as strings, and the only concrete game class it depends on is the SaveData component.
///
[System.Serializable]
public class SavePointData
{
[SerializeField] protected string savePointKey;
- [SerializeField] protected string savePointDescription;
- [SerializeField] protected string sceneName;
- [SerializeField] protected List flowchartDatas = new List();
- protected static SavePointData tempSavePointData;
+ [SerializeField] protected string savePointDescription;
- protected static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
- {
- // Additive scene loads and non-matching scene loads could happen if someone is using
- // Fungus as part of a bigger game, so just ignore these events and hope they know what they're doing.
- if (mode == LoadSceneMode.Additive ||
- scene.name != tempSavePointData.SceneName)
- {
- return;
- }
- SceneManager.sceneLoaded -= OnSceneLoaded;
+ [SerializeField] protected string sceneName;
- var saveDatas = GameObject.FindObjectsOfType();
- foreach (var saveData in saveDatas)
- {
- saveData.Decode(tempSavePointData);
- }
+ [SerializeField] protected List saveDataItems = new List();
- SaveManagerSignals.DoSavePointLoaded(tempSavePointData.savePointKey);
- }
-
protected static SavePointData Create(string _savePointKey, string _savePointDescription, string _sceneName)
{
var savePointData = new SavePointData();
@@ -67,9 +49,10 @@ namespace Fungus
public string SceneName { get { return sceneName; } set { sceneName = value; } }
///
- /// Gets or sets the encoded Flowchart data for the Save Point.
+ /// Gets the list of save data items.
///
- public List FlowchartDatas { get { return flowchartDatas; } set { flowchartDatas = value; } }
+ /// The save data items.
+ public List SaveDataItems { get { return saveDataItems; } }
///
/// Encodes a new Save Point to data and converts it to JSON text format.
@@ -77,11 +60,12 @@ namespace Fungus
public static string Encode(string _savePointKey, string _savePointDescription, string _sceneName)
{
var savePointData = Create(_savePointKey, _savePointDescription, _sceneName);
-
- var saveDatas = GameObject.FindObjectsOfType();
- foreach (var saveData in saveDatas)
+
+ // Look for a SaveData component in the scene to populate the save data items.
+ var saveData = GameObject.FindObjectOfType();
+ if (saveData != null)
{
- saveData.Encode(savePointData);
+ saveData.Encode(savePointData.SaveDataItems);
}
return JsonUtility.ToJson(savePointData, true);
@@ -92,10 +76,33 @@ namespace Fungus
///
public static void Decode(string saveDataJSON)
{
- tempSavePointData = JsonUtility.FromJson(saveDataJSON);
-
- SceneManager.sceneLoaded += OnSceneLoaded;
- SceneManager.LoadScene(tempSavePointData.SceneName);
+ var savePointData = JsonUtility.FromJson(saveDataJSON);
+
+ UnityAction onSceneLoadedAction = null;
+
+ onSceneLoadedAction = (scene, mode) => {
+ // Additive scene loads and non-matching scene loads could happen if the client is using the
+ // SceneManager directly. We just ignore these events and hope they know what they're doing!
+ if (mode == LoadSceneMode.Additive ||
+ scene.name != savePointData.SceneName)
+ {
+ return;
+ }
+
+ SceneManager.sceneLoaded -= onSceneLoadedAction;
+
+ // Look for a SaveData component in the scene to process the save data items.
+ var saveData = GameObject.FindObjectOfType();
+ if (saveData != null)
+ {
+ saveData.Decode(savePointData.SaveDataItems);
+ }
+
+ SaveManagerSignals.DoSavePointLoaded(savePointData.savePointKey);
+ };
+
+ SceneManager.sceneLoaded += onSceneLoadedAction;
+ SceneManager.LoadScene(savePointData.SceneName);
}
#endregion