diff --git a/Assets/Fungus/Scripts/Commands/SavePoint.cs b/Assets/Fungus/Scripts/Commands/SavePoint.cs
index c7793e65..c30ebbac 100644
--- a/Assets/Fungus/Scripts/Commands/SavePoint.cs
+++ b/Assets/Fungus/Scripts/Commands/SavePoint.cs
@@ -2,6 +2,7 @@
// It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE)
using UnityEngine;
+using System.Collections;
namespace Fungus
{
@@ -10,18 +11,31 @@ namespace Fungus
"Creates a Save Point and adds it to the Save History. The player can save the Save History to peristent storage and load it again later.")]
public class SavePoint : Command
{
- [Tooltip("A string key which uniquely identifies this save point. If empty then the parent Block's name will be used.")]
+ [Tooltip("A string key which uniquely identifies this save point. If you leave this empty then the parent Block's name will be used.")]
[SerializeField] protected string savePointKey = "";
- [Tooltip("A short description of this save point. If empty then the current time and date will be used.")]
+ [Tooltip("A short description of this save point. If you leave this empty then the current time and date will be used.")]
[SerializeField] protected string savePointDescription;
- [Tooltip("Fire an event that will be handled by any Save Point Loaded event handler with matching key.")]
+ [Tooltip("Fire a Save Point Loaded event when this command executes.")]
[SerializeField] protected bool fireEvent = true;
- [Tooltip("Resume execution from this command after loading a save point.")]
+ [Tooltip("Resume execution from here after loading this Save Point.")]
[SerializeField] protected bool resumeFromHere = true;
+ protected virtual void Start()
+ {
+ // Each scene should have one Save Point with the 'Start' key.
+ // We automatically start execution from this command whenever the scene starts 'normally' (i.e. first play, restart or scene load via the Load Scene command or SceneManager.LoadScene).
+ // If on the other hand, the scene was loaded by loading a Save Point then the Save Manager handles resuming execution at the appropriate point, so we don't need to do anything here.
+
+ if (string.Compare(SavePointKey, "Start", true) == 0 &&
+ !FungusManager.Instance.SaveManager.HasLoadedSavePoint)
+ {
+ GetFlowchart().ExecuteBlock(ParentBlock, CommandIndex);
+ }
+ }
+
#region Public members
///
@@ -69,7 +83,7 @@ namespace Fungus
if (fireEvent)
{
- SavePointLoaded.NotifyEventHandlers(savePointKey);
+ SavePointLoaded.NotifyEventHandlers(SavePointKey);
}
Continue();
diff --git a/Assets/Fungus/Scripts/Components/SaveManager.cs b/Assets/Fungus/Scripts/Components/SaveManager.cs
index bc8b627c..8284861f 100644
--- a/Assets/Fungus/Scripts/Components/SaveManager.cs
+++ b/Assets/Fungus/Scripts/Components/SaveManager.cs
@@ -1,4 +1,5 @@
using UnityEngine;
+using System.Collections;
namespace Fungus
{
@@ -38,8 +39,37 @@ namespace Fungus
return false;
}
+ protected virtual void OnEnable()
+ {
+ SaveManagerSignals.OnSavePointLoaded += OnSavePointLoaded;
+ }
+
+ protected virtual void OnDisable()
+ {
+ SaveManagerSignals.OnSavePointLoaded -= OnSavePointLoaded;
+ }
+
+ protected virtual void OnSavePointLoaded(string savePointKey)
+ {
+ // Flag that a save point was loaded.
+ // The flag remains set for 1 frame to give other components enough time to poll it in their Start method.
+ HasLoadedSavePoint = true;
+ StartCoroutine(ResetHasLoadedSavePoint());
+ }
+
+ protected virtual IEnumerator ResetHasLoadedSavePoint()
+ {
+ yield return new WaitForEndOfFrame();
+ HasLoadedSavePoint = false;
+ }
+
#region Public members
+ ///
+ /// The default key used for storing save game data in PlayerPrefs.
+ ///
+ public const string DefaultSaveDataKey = "save_data";
+
///
/// Returns the number of Save Points in the Save History.
///
@@ -50,34 +80,32 @@ namespace Fungus
///
public virtual int NumRewoundSavePoints { get { return saveHistory.NumRewoundSavePoints; } }
+ public virtual bool HasLoadedSavePoint { get; private set; }
+
///
/// Writes the Save History to persistent storage.
///
- public virtual void Save(string saveDataKey)
+ public virtual void Save(string saveDataKey = DefaultSaveDataKey)
{
WriteSaveHistory(saveDataKey);
-
- SaveManagerSignals.DoGameSaved(saveDataKey);
}
///
/// Loads the Save History from persistent storage.
///
- public void Load(string saveDataKey)
+ public void Load(string saveDataKey = DefaultSaveDataKey)
{
if (ReadSaveHistory(saveDataKey))
{
saveHistory.ClearRewoundSavePoints();
saveHistory.LoadLatestSavePoint();
-
- SaveManagerSignals.DoGameLoaded(saveDataKey);
}
}
///
/// Deletes a previously stored Save History from persistent storage.
///
- public void Delete(string saveDataKey)
+ public void Delete(string saveDataKey = DefaultSaveDataKey)
{
PlayerPrefs.DeleteKey(saveDataKey);
PlayerPrefs.Save();
@@ -86,7 +114,7 @@ namespace Fungus
///
/// Returns true if save data has previously been stored using this key.
///
- public bool SaveDataExists(string saveDataKey)
+ public bool SaveDataExists(string saveDataKey = DefaultSaveDataKey)
{
return PlayerPrefs.HasKey(saveDataKey);
}
@@ -108,7 +136,7 @@ namespace Fungus
{
if (saveHistory.NumSavePoints > 0)
{
- // Can't rewind the first save point (new_game)
+ // Rewinding the first save point is not permitted
if (saveHistory.NumSavePoints > 1)
{
saveHistory.Rewind();
@@ -142,8 +170,8 @@ namespace Fungus
/// Starts Block execution based on a Save Point Key
/// The execution order is:
/// 1. Save Point Loaded event handlers with a matching key.
- /// 2. First Save Point command (in any Block) with matching key. Execution starts at following command.
- /// 3. Any label in any block with name matching the key. Execution starts at following command.
+ /// 2. First Save Point command (in any Block) with matching key. Execution starts at the following command.
+ /// 3. Any label in any block with name matching the key. Execution starts at the following command.
///
public static void ExecuteBlocks(string savePointKey)
{
diff --git a/Assets/Fungus/Scripts/Components/SaveMenu.cs b/Assets/Fungus/Scripts/Components/SaveMenu.cs
index 1f015364..3dedb8dd 100644
--- a/Assets/Fungus/Scripts/Components/SaveMenu.cs
+++ b/Assets/Fungus/Scripts/Components/SaveMenu.cs
@@ -10,12 +10,8 @@ namespace Fungus
///
public class SaveMenu : MonoBehaviour
{
- const string SaveDataKey = "save_data";
-
- const string NewGameSavePointKey = "new_game";
-
- [Tooltip("On scene start, execute any Save Point Loaded event handlers which have the 'new_game' key")]
- [SerializeField] protected bool autoStartGame = true;
+ [Tooltip("Automatically load the most recently saved game on startup")]
+ [SerializeField] protected bool loadOnStart = true;
[Tooltip("Delete the save game data from disk when player restarts the game. Useful for testing, but best switched off for release builds.")]
[SerializeField] protected bool restartDeletesSave = false;
@@ -72,32 +68,19 @@ namespace Fungus
// Assume that the first scene that contains the SaveMenu is also the scene to load on restart.
startScene = SceneManager.GetActiveScene().name;
-
if (!saveMenuActive)
{
saveMenuGroup.alpha = 0f;
}
- var saveManager = FungusManager.Instance.SaveManager;
-
- if (autoStartGame &&
- saveManager.NumSavePoints == 0)
+ if (loadOnStart)
{
- StartNewGame();
+ var saveManager = FungusManager.Instance.SaveManager;
+ if (saveManager.SaveDataExists())
+ {
+ saveManager.Load();
+ }
}
-
- CheckSavePointKeys();
- }
-
- protected virtual void StartNewGame()
- {
- var saveManager = FungusManager.Instance.SaveManager;
-
- // Create an initial save point
- saveManager.AddSavePoint(NewGameSavePointKey, "");
-
- // Start game execution
- SaveManager.ExecuteBlocks(NewGameSavePointKey);
}
protected virtual void Update()
@@ -112,7 +95,7 @@ namespace Fungus
}
if (loadButton != null)
{
- loadButton.interactable = saveManager.SaveDataExists(SaveDataKey);
+ loadButton.interactable = saveManager.SaveDataExists();
}
if (rewindButton != null)
{
@@ -124,33 +107,6 @@ namespace Fungus
}
}
- ///
- /// Warns if duplicate SavePointKeys are found.
- ///
- protected void CheckSavePointKeys()
- {
- List keys = new List();
-
- var savePoints = GameObject.FindObjectsOfType();
-
- foreach (var savePoint in savePoints)
- {
- if (string.IsNullOrEmpty(savePoint.SavePointKey))
- {
- continue;
- }
-
- if (keys.Contains(savePoint.SavePointKey))
- {
- Debug.LogError("Save Point Key " + savePoint.SavePointKey + " is defined multiple times.");
- }
- else
- {
- keys.Add(savePoint.SavePointKey);
- }
- }
- }
-
protected void PlayClickSound()
{
if (clickAudioSource != null)
@@ -159,21 +115,6 @@ namespace Fungus
}
}
- ///
- /// Callback for the restart scene load
- ///
- protected void OnSceneLoaded(Scene scene, LoadSceneMode mode)
- {
- if (scene.name != startScene)
- {
- return;
- }
-
- SceneManager.sceneLoaded -= OnSceneLoaded;
-
- StartNewGame();
- }
-
#region Public methods
///
@@ -220,7 +161,7 @@ namespace Fungus
if (saveManager.NumSavePoints > 0)
{
PlayClickSound();
- saveManager.Save(SaveDataKey);
+ saveManager.Save();
}
}
@@ -231,10 +172,10 @@ namespace Fungus
{
var saveManager = FungusManager.Instance.SaveManager;
- if (saveManager.SaveDataExists(SaveDataKey))
+ if (saveManager.SaveDataExists())
{
PlayClickSound();
- saveManager.Load(SaveDataKey);
+ saveManager.Load();
}
}
@@ -277,17 +218,16 @@ namespace Fungus
return;
}
- var saveManager = FungusManager.Instance.SaveManager;
-
PlayClickSound();
+ // Reset the Save History for a new game
+ var saveManager = FungusManager.Instance.SaveManager;
saveManager.ClearHistory();
if (restartDeletesSave)
{
- saveManager.Delete(SaveDataKey);
+ saveManager.Delete();
}
- SceneManager.sceneLoaded += OnSceneLoaded;
SceneManager.LoadScene(startScene);
}
diff --git a/Assets/Fungus/Scripts/Signals/SaveManagerSignals.cs b/Assets/Fungus/Scripts/Signals/SaveManagerSignals.cs
index 56878ade..385d80eb 100644
--- a/Assets/Fungus/Scripts/Signals/SaveManagerSignals.cs
+++ b/Assets/Fungus/Scripts/Signals/SaveManagerSignals.cs
@@ -12,18 +12,11 @@ namespace Fungus
#region Public members
///
- /// GameSaved signal. Sent just after the game is saved.
+ /// SavePointLoaded signal. Sent just after a SavePoint is loaded.
///
- public static event GameSavedHandler OnGameSaved;
- public delegate void GameSavedHandler(string saveDataKey);
- public static void DoGameSaved(string saveDataKey) { if (OnGameSaved != null) OnGameSaved(saveDataKey); }
-
- ///
- /// GameLoaded signal. Sent just after the game is loaded.
- ///
- public static event GameLoadedHandler OnGameLoaded;
- public delegate void GameLoadedHandler(string saveDataKey);
- public static void DoGameLoaded(string saveDataKey) { if (OnGameLoaded != null) OnGameLoaded(saveDataKey); }
+ public static event SavePointLoadedHandler OnSavePointLoaded;
+ public delegate void SavePointLoadedHandler(string savePointKey);
+ public static void DoSavePointLoaded(string savePointKey) { if (OnSavePointLoaded != null) OnSavePointLoaded(savePointKey); }
///
/// SavePointAdded signal. Sent when a new save point is added to the save history (typically via the Save Point command).
diff --git a/Assets/Fungus/Scripts/Utils/FungusConstants.cs b/Assets/Fungus/Scripts/Utils/FungusConstants.cs
index 9edc868d..f7276c9d 100644
--- a/Assets/Fungus/Scripts/Utils/FungusConstants.cs
+++ b/Assets/Fungus/Scripts/Utils/FungusConstants.cs
@@ -27,8 +27,19 @@ namespace Fungus
///
public const string DefaultBlockName = "New Block";
+ ///
+ /// The default choice block color.
+ ///
public static Color DefaultChoiceBlockTint = new Color(1.0f, 0.627f, 0.313f, 1.0f);
+
+ ///
+ /// The default event block color.
+ ///
public static Color DefaultEventBlockTint = new Color(0.784f, 0.882f, 1.0f, 1.0f);
+
+ ///
+ /// The default process block color.
+ ///
public static Color DefaultProcessBlockTint = new Color(1.0f, 0.882f, 0.0f, 1.0f);
#endregion
diff --git a/Assets/Fungus/Scripts/Utils/SavePointData.cs b/Assets/Fungus/Scripts/Utils/SavePointData.cs
index 78cc8b54..991f44e3 100644
--- a/Assets/Fungus/Scripts/Utils/SavePointData.cs
+++ b/Assets/Fungus/Scripts/Utils/SavePointData.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
+using System.Collections;
namespace Fungus
{
@@ -34,6 +35,8 @@ namespace Fungus
}
SaveManager.ExecuteBlocks(savePointData.savePointKey);
+
+ SaveManagerSignals.DoSavePointLoaded(savePointData.savePointKey);
}
protected static SavePointData Create(string _savePointKey, string _savePointDescription, string _sceneName)
diff --git a/Assets/FungusExamples/SaveGame/SaveExample.unity b/Assets/FungusExamples/SaveGame/SaveExample.unity
index 7d38358f..a08d47f7 100644
--- a/Assets/FungusExamples/SaveGame/SaveExample.unity
+++ b/Assets/FungusExamples/SaveGame/SaveExample.unity
@@ -1287,12 +1287,12 @@ GameObject:
- component: {fileID: 1889213511}
- component: {fileID: 1889213509}
- component: {fileID: 1889213470}
- - component: {fileID: 1889213471}
- component: {fileID: 1889213473}
- component: {fileID: 1889213481}
- component: {fileID: 1889213480}
- - component: {fileID: 1889213479}
+ - component: {fileID: 1889213478}
- component: {fileID: 1889213475}
+ - component: {fileID: 1889213471}
m_Layer: 0
m_Name: Flowchart
m_TagString: Untagged
@@ -1302,7 +1302,7 @@ GameObject:
m_IsActive: 1
--- !u!114 &1889213470
MonoBehaviour:
- m_ObjectHideFlags: 0
+ m_ObjectHideFlags: 2
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1889213469}
@@ -1322,7 +1322,7 @@ MonoBehaviour:
itemId: 52
blockName: Play Music 1
description:
- eventHandler: {fileID: 1889213471}
+ eventHandler: {fileID: 1889213475}
commandList:
- {fileID: 1889213473}
--- !u!114 &1889213471
@@ -1336,13 +1336,14 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 9ca33a026786245d4b10323b87e84d5f, type: 3}
m_Name:
m_EditorClassIdentifier:
- parentBlock: {fileID: 1889213470}
+ parentBlock: {fileID: 1889213481}
savePointKeys:
- - new_game
- - Queens Chamber
+ - Use Umbrella
+ - Duck Down
+ - The Queen
--- !u!114 &1889213473
MonoBehaviour:
- m_ObjectHideFlags: 0
+ m_ObjectHideFlags: 2
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1889213469}
@@ -1394,9 +1395,10 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 9ca33a026786245d4b10323b87e84d5f, type: 3}
m_Name:
m_EditorClassIdentifier:
- parentBlock: {fileID: 1889213482}
+ parentBlock: {fileID: 1889213470}
savePointKeys:
- - new_game
+ - Start
+ - Queens Chamber
--- !u!114 &1889213476
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -1410,7 +1412,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
version: 1
- scrollPos: {x: -57.30224, y: -63.688995}
+ scrollPos: {x: -103.9434, y: -49.980755}
variablesScrollPos: {x: 0, y: 0}
variablesExpanded: 1
blockViewHeight: 400
@@ -1422,7 +1424,7 @@ MonoBehaviour:
width: 1502.7736
height: 1138.5048
selectedBlocks:
- - {fileID: 1889213481}
+ - {fileID: 1889213500}
selectedCommands: []
variables:
- {fileID: 1889213489}
@@ -1450,25 +1452,26 @@ Transform:
m_Father: {fileID: 0}
m_RootOrder: 7
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
---- !u!114 &1889213479
+--- !u!114 &1889213478
MonoBehaviour:
- m_ObjectHideFlags: 0
+ m_ObjectHideFlags: 2
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1889213469}
m_Enabled: 1
m_EditorHideFlags: 0
- m_Script: {fileID: 11500000, guid: 9ca33a026786245d4b10323b87e84d5f, type: 3}
+ m_Script: {fileID: 11500000, guid: 0b115619cb83b4d6ab8047d0e9407403, type: 3}
m_Name:
m_EditorClassIdentifier:
- parentBlock: {fileID: 1889213481}
- savePointKeys:
- - Use Umbrella
- - Duck Down
- - The Queen
+ itemId: 61
+ indentLevel: 0
+ savePointKey:
+ savePointDescription:
+ fireEvent: 1
+ resumeFromHere: 1
--- !u!114 &1889213480
MonoBehaviour:
- m_ObjectHideFlags: 0
+ m_ObjectHideFlags: 2
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1889213469}
@@ -1485,7 +1488,7 @@ MonoBehaviour:
fadeDuration: 1
--- !u!114 &1889213481
MonoBehaviour:
- m_ObjectHideFlags: 0
+ m_ObjectHideFlags: 2
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1889213469}
@@ -1496,8 +1499,8 @@ MonoBehaviour:
m_EditorClassIdentifier:
nodeRect:
serializedVersion: 2
- x: 81.28943
- y: 288.5421
+ x: 78.28943
+ y: 294.5421
width: 120
height: 40
tint: {r: 1, g: 1, b: 1, a: 1}
@@ -1505,7 +1508,7 @@ MonoBehaviour:
itemId: 59
blockName: Play Music 2
description:
- eventHandler: {fileID: 1889213479}
+ eventHandler: {fileID: 1889213471}
commandList:
- {fileID: 1889213480}
--- !u!114 &1889213482
@@ -1528,10 +1531,11 @@ MonoBehaviour:
tint: {r: 1, g: 1, b: 1, a: 1}
useCustomTint: 0
itemId: 16
- blockName: new_game
+ blockName: Start
description:
- eventHandler: {fileID: 1889213475}
+ eventHandler: {fileID: 0}
commandList:
+ - {fileID: 1889213478}
- {fileID: 1889213474}
- {fileID: 1889213507}
- {fileID: 1889213504}
@@ -1631,9 +1635,7 @@ MonoBehaviour:
itemId: 21
indentLevel: 0
savePointKey:
- savePointDescription:
- stringRef: {fileID: 0}
- stringVal:
+ savePointDescription:
fireEvent: 1
resumeFromHere: 1
--- !u!114 &1889213488
@@ -1923,13 +1925,13 @@ MonoBehaviour:
nodeRect:
serializedVersion: 2
x: 542.1676
- y: 144.44673
+ y: 143.44673
width: 120
height: 40
tint: {r: 1, g: 1, b: 1, a: 1}
useCustomTint: 0
itemId: 31
- blockName: TheQueen
+ blockName: The Queen
description:
eventHandler: {fileID: 0}
commandList:
@@ -1953,9 +1955,7 @@ MonoBehaviour:
itemId: 35
indentLevel: 0
savePointKey:
- savePointDescription:
- stringRef: {fileID: 0}
- stringVal:
+ savePointDescription:
fireEvent: 1
resumeFromHere: 1
--- !u!114 &1889213502
@@ -1972,9 +1972,7 @@ MonoBehaviour:
itemId: 34
indentLevel: 0
savePointKey:
- savePointDescription:
- stringRef: {fileID: 0}
- stringVal:
+ savePointDescription:
fireEvent: 1
resumeFromHere: 1
--- !u!114 &1889213503
@@ -2239,9 +2237,7 @@ MonoBehaviour:
itemId: 43
indentLevel: 0
savePointKey:
- savePointDescription:
- stringRef: {fileID: 0}
- stringVal:
+ savePointDescription:
fireEvent: 1
resumeFromHere: 1
--- !u!1 &2025975869