Browse Source

Improved save game example. Save Point Loaded now handles multiple keys.

master
Christopher 8 years ago
parent
commit
d2444982dc
  1. 5
      Assets/Fungus/Scripts/Components/SaveManager.cs
  2. 23
      Assets/Fungus/Scripts/Components/SaveMenu.cs
  3. 54
      Assets/Fungus/Scripts/Editor/EventHandlerEditor.cs
  4. 29
      Assets/Fungus/Scripts/Editor/SavePointLoadedEditor.cs
  5. 12
      Assets/Fungus/Scripts/Editor/SavePointLoadedEditor.cs.meta
  6. 11
      Assets/Fungus/Scripts/EventHandlers/SavePointLoaded.cs
  7. 3
      Assets/Fungus/Scripts/Utils/SaveHistory.cs
  8. 82
      Assets/Fungus/Scripts/Utils/SavePointData.cs
  9. 1037
      Assets/FungusExamples/SaveGame/SaveExample.unity

5
Assets/Fungus/Scripts/Components/SaveManager.cs

@ -107,8 +107,13 @@ namespace Fungus
public virtual void Rewind() public virtual void Rewind()
{ {
if (saveHistory.NumSavePoints > 0) if (saveHistory.NumSavePoints > 0)
{
// Can't rewind the first save point (new_game)
if (saveHistory.NumSavePoints > 1)
{ {
saveHistory.Rewind(); saveHistory.Rewind();
}
saveHistory.LoadLatestSavePoint(); saveHistory.LoadLatestSavePoint();
} }
} }

23
Assets/Fungus/Scripts/Components/SaveMenu.cs

@ -72,22 +72,34 @@ namespace Fungus
// Assume that the first scene that contains the SaveMenu is also the scene to load on restart. // Assume that the first scene that contains the SaveMenu is also the scene to load on restart.
startScene = SceneManager.GetActiveScene().name; startScene = SceneManager.GetActiveScene().name;
var saveManager = FungusManager.Instance.SaveManager;
if (!saveMenuActive) if (!saveMenuActive)
{ {
saveMenuGroup.alpha = 0f; saveMenuGroup.alpha = 0f;
} }
var saveManager = FungusManager.Instance.SaveManager;
if (autoStartGame && if (autoStartGame &&
saveManager.NumSavePoints == 0) saveManager.NumSavePoints == 0)
{ {
SavePointLoaded.NotifyEventHandlers(NewGameSavePointKey); StartNewGame();
} }
CheckSavePointKeys(); CheckSavePointKeys();
} }
protected virtual void StartNewGame()
{
var saveManager = FungusManager.Instance.SaveManager;
// Create an initial save point
saveManager.AddSavePoint(NewGameSavePointKey, "");
// Start game execution
SavePointData.ExecuteBlocks(NewGameSavePointKey);
}
protected virtual void Update() protected virtual void Update()
{ {
var saveManager = FungusManager.Instance.SaveManager; var saveManager = FungusManager.Instance.SaveManager;
@ -104,7 +116,7 @@ namespace Fungus
} }
if (rewindButton != null) if (rewindButton != null)
{ {
rewindButton.interactable = saveManager.NumSavePoints > 1; rewindButton.interactable = saveManager.NumSavePoints > 0;
} }
if (forwardButton != null) if (forwardButton != null)
{ {
@ -158,7 +170,8 @@ namespace Fungus
} }
SceneManager.sceneLoaded -= OnSceneLoaded; SceneManager.sceneLoaded -= OnSceneLoaded;
SavePointLoaded.NotifyEventHandlers(NewGameSavePointKey);
StartNewGame();
} }
#region Public methods #region Public methods
@ -233,7 +246,7 @@ namespace Fungus
PlayClickSound(); PlayClickSound();
var saveManager = FungusManager.Instance.SaveManager; var saveManager = FungusManager.Instance.SaveManager;
if (saveManager.NumSavePoints > 1) if (saveManager.NumSavePoints > 0)
{ {
saveManager.Rewind(); saveManager.Rewind();
} }

54
Assets/Fungus/Scripts/Editor/EventHandlerEditor.cs

@ -9,6 +9,36 @@ namespace Fungus.EditorUtils
[CustomEditor (typeof(EventHandler), true)] [CustomEditor (typeof(EventHandler), true)]
public class EventHandlerEditor : Editor public class EventHandlerEditor : Editor
{ {
protected virtual void DrawProperties()
{
SerializedProperty iterator = serializedObject.GetIterator();
bool enterChildren = true;
while (iterator.NextVisible(enterChildren))
{
enterChildren = false;
if (iterator.name == "m_Script")
{
continue;
}
EditorGUILayout.PropertyField(iterator, true, new GUILayoutOption[0]);
}
}
protected virtual void DrawHelpBox()
{
EventHandler t = target as EventHandler;
EventHandlerInfoAttribute info = EventHandlerEditor.GetEventHandlerInfo(t.GetType());
if (info != null &&
info.HelpText.Length > 0)
{
EditorGUILayout.HelpBox(info.HelpText, MessageType.Info);
}
}
#region Public members
/// <summary> /// <summary>
/// Returns the class attribute info for an event handler class. /// Returns the class attribute info for an event handler class.
/// </summary> /// </summary>
@ -33,29 +63,13 @@ namespace Fungus.EditorUtils
// Doing so could cause block.commandList to contain null entries. // Doing so could cause block.commandList to contain null entries.
// To avoid this we manually display all properties, except for m_Script. // To avoid this we manually display all properties, except for m_Script.
serializedObject.Update(); serializedObject.Update();
SerializedProperty iterator = serializedObject.GetIterator();
bool enterChildren = true;
while (iterator.NextVisible(enterChildren))
{
enterChildren = false;
if (iterator.name == "m_Script")
{
continue;
}
EditorGUILayout.PropertyField(iterator, true, new GUILayoutOption[0]);
}
EventHandler t = target as EventHandler; DrawProperties();
EventHandlerInfoAttribute info = EventHandlerEditor.GetEventHandlerInfo(t.GetType()); DrawHelpBox();
if (info != null &&
info.HelpText.Length > 0)
{
EditorGUILayout.HelpBox(info.HelpText, MessageType.Info);
}
serializedObject.ApplyModifiedProperties(); serializedObject.ApplyModifiedProperties();
} }
#endregion
} }
} }

29
Assets/Fungus/Scripts/Editor/SavePointLoadedEditor.cs

@ -0,0 +1,29 @@
using UnityEngine;
using UnityEditor;
using Rotorz.ReorderableList;
namespace Fungus.EditorUtils
{
[CustomEditor (typeof(SavePointLoaded), true)]
public class SavePointLoadedEditor : EventHandlerEditor
{
protected SerializedProperty savePointKeysProp;
protected virtual void OnEnable()
{
savePointKeysProp = serializedObject.FindProperty("savePointKeys");
}
public override void DrawInspectorGUI()
{
serializedObject.Update();
ReorderableListGUI.Title("Save Point Keys");
ReorderableListGUI.ListField(savePointKeysProp);
DrawHelpBox();
serializedObject.ApplyModifiedProperties();
}
}
}

12
Assets/Fungus/Scripts/Editor/SavePointLoadedEditor.cs.meta

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 395934d0b0e6a48a396a25348aeaade5
timeCreated: 1484049679
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

11
Assets/Fungus/Scripts/EventHandlers/SavePointLoaded.cs

@ -8,17 +8,22 @@ namespace Fungus
{ {
[EventHandlerInfo("Scene", [EventHandlerInfo("Scene",
"Save Point Loaded", "Save Point Loaded",
"Execute this block when a saved point is loaded.")] "Execute this block when a saved point is loaded. Use the 'new_game' key to handle game start.")]
public class SavePointLoaded : EventHandler public class SavePointLoaded : EventHandler
{ {
[Tooltip("Block will execute if the Save Key of the loaded save point matches this save key.")] [Tooltip("Block will execute if the Save Key of the loaded save point matches this save key.")]
[SerializeField] protected string savePointKey = ""; [SerializeField] protected List<string> savePointKeys = new List<string>();
protected void OnSavePointLoaded(string _savePointKey) protected void OnSavePointLoaded(string _savePointKey)
{ {
if (string.Compare(savePointKey, _savePointKey, true) == 0) for (int i = 0; i < savePointKeys.Count; i++)
{
var key = savePointKeys[i];
if (string.Compare(key, _savePointKey, true) == 0)
{ {
ExecuteBlock(); ExecuteBlock();
break;
}
} }
} }

3
Assets/Fungus/Scripts/Utils/SaveHistory.cs

@ -39,6 +39,9 @@ namespace Fungus
/// </summary> /// </summary>
public void AddSavePoint(string savePointKey, string savePointDescription) public void AddSavePoint(string savePointKey, string savePointDescription)
{ {
// Creating a new Save Point invalidates all rewound Save Points, so delete them.
ClearRewoundSavePoints();
string sceneName = SceneManager.GetActiveScene().name; string sceneName = SceneManager.GetActiveScene().name;
var savePointData = SavePointData.Encode(savePointKey, savePointDescription, sceneName); var savePointData = SavePointData.Encode(savePointKey, savePointDescription, sceneName);
savePoints.Add(savePointData); savePoints.Add(savePointData);

82
Assets/Fungus/Scripts/Utils/SavePointData.cs

@ -36,43 +36,6 @@ namespace Fungus
ExecuteBlocks(savePointData.savePointKey); ExecuteBlocks(savePointData.savePointKey);
} }
protected static void ExecuteBlocks(string savePointKey)
{
SavePointLoaded.NotifyEventHandlers(savePointKey);
// Execute any block containing a SavePoint command matching the save key, with Resume From Here enabled
var savePoints = Object.FindObjectsOfType<SavePoint>();
for (int i = 0; i < savePoints.Length; i++)
{
var savePoint = savePoints[i];
if (savePoint.ResumeFromHere &&
string.Compare(savePoint.SavePointKey, savePointKey, 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<Label>();
for (int i = 0; i < labels.Length; i++)
{
var label = labels[i];
if (string.Compare(label.Key, savePointKey, true) == 0)
{
int index = label.CommandIndex;
var block = label.ParentBlock;
var flowchart = label.GetFlowchart();
flowchart.ExecuteBlock(block, index + 1);
}
}
}
protected static SavePointData Create(string _savePointKey, string _savePointDescription, string _sceneName) protected static SavePointData Create(string _savePointKey, string _savePointDescription, string _sceneName)
{ {
var savePointData = new SavePointData(); var savePointData = new SavePointData();
@ -137,6 +100,51 @@ namespace Fungus
SceneManager.LoadScene(tempSavePointData.SceneName); SceneManager.LoadScene(tempSavePointData.SceneName);
} }
/// <summary>
/// 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.
/// </summary>
public static void ExecuteBlocks(string savePointKey)
{
// Execute Save Point Loaded event handlers with matching key.
SavePointLoaded.NotifyEventHandlers(savePointKey);
// Execute any block containing a SavePoint command matching the save key, with Resume From Here enabled
var savePoints = Object.FindObjectsOfType<SavePoint>();
for (int i = 0; i < savePoints.Length; i++)
{
var savePoint = savePoints[i];
if (savePoint.ResumeFromHere &&
string.Compare(savePoint.SavePointKey, savePointKey, 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<Label>();
for (int i = 0; i < labels.Length; i++)
{
var label = labels[i];
if (string.Compare(label.Key, savePointKey, true) == 0)
{
int index = label.CommandIndex;
var block = label.ParentBlock;
var flowchart = label.GetFlowchart();
flowchart.ExecuteBlock(block, index + 1);
}
}
}
#endregion #endregion
} }
} }

1037
Assets/FungusExamples/SaveGame/SaveExample.unity

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save