Browse Source

Improved save game system.

- Went back to having to explicitly load / save game variables
master
chrisgregan 11 years ago
parent
commit
84cebac487
  1. 26
      Assets/Fungus/Scripts/Game.cs
  2. 17
      Assets/Fungus/Scripts/GameController.cs
  3. 179
      Assets/Fungus/Scripts/Variables.cs

26
Assets/Fungus/Scripts/Game.cs

@ -31,13 +31,6 @@ namespace Fungus
*/ */
public bool showLinks = true; public bool showLinks = true;
/**
* Deletes all previously stored variables on launch.
* Disable this if you want to have game variables persist between game launches.
* It is then up to you to provide an in-game option to reset game variables.
*/
public bool deleteVariables = true;
/** /**
* Time for fade transition to complete when moving to a different Room. * Time for fade transition to complete when moving to a different Room.
*/ */
@ -123,11 +116,6 @@ namespace Fungus
commandQueue.AddCommand(new Command.MoveToRoom(activeRoom)); commandQueue.AddCommand(new Command.MoveToRoom(activeRoom));
commandQueue.Execute(); commandQueue.Execute();
} }
if (deleteVariables)
{
Variables.DeleteAll();
}
} }
public virtual void Update() public virtual void Update()
@ -186,24 +174,24 @@ namespace Fungus
} }
/** /**
* Save the current game variables to persistant storage. * Save the current game variables to persistant storage using a save game name.
* Store the currently loaded scene name so that Game.LoadGame() can automatically move to the appropriate scene. * Stores the currently loaded scene name so that Game.LoadGame() can automatically move to the appropriate scene.
*/ */
public void SaveGame() public void SaveGame(string saveName = "_fungus")
{ {
SetString("_scene", Application.loadedLevelName); Variables.SetString("_scene", Application.loadedLevelName);
Variables.Save(); Variables.Save(saveName);
} }
/** /**
* Loads the current game state from persistant storage. * Loads the current game state from persistant storage using a save game name.
* This will cause the scene specified in the "_scene" string to be loaded. * This will cause the scene specified in the "_scene" string to be loaded.
* Each scene in your game should contain the necessary code to restore the current game state based on saved data. * Each scene in your game should contain the necessary code to restore the current game state based on saved data.
* @param saveName The name of the saved game data. * @param saveName The name of the saved game data.
*/ */
public void LoadGame(string saveName = "_fungus") public void LoadGame(string saveName = "_fungus")
{ {
Variables.SetSaveName(saveName); Variables.Load(saveName);
string sceneName = Variables.GetString("_scene"); string sceneName = Variables.GetString("_scene");
if (sceneName.Length > 0) if (sceneName.Length > 0)
{ {

17
Assets/Fungus/Scripts/GameController.cs

@ -88,20 +88,11 @@ namespace Fungus
* Save the current game state to persistant storage. * Save the current game state to persistant storage.
* @param saveName The name of the saved game data. * @param saveName The name of the saved game data.
*/ */
[Obsolete("Use Save() instead and use Variables.SetSaveName() if you need to set the save name.")] public static void Save(string saveName = "_fungus")
public static void Save(string saveName)
{
GameController.Save();
}
/**
* Saves the current game variables to persistant storage.
*/
public static void Save()
{ {
CommandQueue commandQueue = Game.GetInstance().commandQueue; CommandQueue commandQueue = Game.GetInstance().commandQueue;
commandQueue.AddCommand(new Command.Call(delegate { commandQueue.AddCommand(new Command.Call(delegate {
Game.GetInstance().SaveGame(); Game.GetInstance().SaveGame(saveName);
})); }));
} }
@ -371,7 +362,9 @@ namespace Fungus
[Obsolete("Use Variables.DeleteKey() instead")] [Obsolete("Use Variables.DeleteKey() instead")]
public static void ClearValue(string key) public static void ClearValue(string key)
{ {
Variables.DeleteKey(key); Variables.SetInteger(key, 0);
Variables.SetFloat(key, 0);
Variables.SetBoolean(key, false);
} }
/** /**

179
Assets/Fungus/Scripts/Variables.cs

@ -1,128 +1,215 @@
using UnityEngine; using UnityEngine;
using System;
using System.Collections; using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
namespace Fungus namespace Fungus
{ {
/** /**
* Peristent data storage class for tracking game state. * Static data storage class for managing global game variables.
* Provides a basic save game system. * Provides save and load functionality for persistent storage between game sessions.
*/ */
public class Variables public class Variables
{ {
static string saveName = "_fungus"; static Dictionary<string, string> stringDict = new Dictionary<string, string>();
static Dictionary<string, int> intDict = new Dictionary<string, int>();
static Dictionary<string, float> floatDict = new Dictionary<string, float>();
static Dictionary<string, bool> boolDict = new Dictionary<string, bool>();
/** /**
* Sets a name to prefix before all keys used with Set & Get methods. * Save the variable dictionaries to persistent storage using a name tag.
* You can use this to support multiple save data profiles, (e.g. for multiple users or a list of checkpoints).
*/ */
static public void SetSaveName(string _saveName) public static void Save(string saveName)
{ {
saveName = _saveName; // Save strings
{
var b = new BinaryFormatter();
var m = new MemoryStream();
b.Serialize(m, stringDict);
PlayerPrefs.SetString(saveName + "." + "stringDict", Convert.ToBase64String(m.GetBuffer()));
} }
/** // Save ints
* Save the variables state to persistent storage. {
*/ var b = new BinaryFormatter();
static public void Save() var m = new MemoryStream();
b.Serialize(m, intDict);
PlayerPrefs.SetString(saveName + "." + "intDict", Convert.ToBase64String(m.GetBuffer()));
}
// Save floats
{ {
var b = new BinaryFormatter();
var m = new MemoryStream();
b.Serialize(m, floatDict);
PlayerPrefs.SetString(saveName + "." + "floatDict", Convert.ToBase64String(m.GetBuffer()));
}
// Save bools
{
var b = new BinaryFormatter();
var m = new MemoryStream();
b.Serialize(m, boolDict);
PlayerPrefs.SetString(saveName + "." + "boolDict", Convert.ToBase64String(m.GetBuffer()));
}
PlayerPrefs.Save(); PlayerPrefs.Save();
} }
/** /**
* Deletes all stored variables. * Loads the variable dictionaries from persistent storage using a name tag.
*/ */
static public void DeleteAll() public static void Load(string saveName)
{
var stringData = PlayerPrefs.GetString(saveName + "." + "stringDict");
if (string.IsNullOrEmpty(stringData))
{
stringDict.Clear();
}
else
{
var b = new BinaryFormatter();
var m = new MemoryStream(Convert.FromBase64String(stringData));
stringDict = (Dictionary<string, string>)b.Deserialize(m);
}
var floatData = PlayerPrefs.GetString(saveName + "." + "floatDict");
if (!string.IsNullOrEmpty(floatData))
{
var b = new BinaryFormatter();
var m = new MemoryStream(Convert.FromBase64String(floatData));
floatDict = b.Deserialize(m) as Dictionary<string, float>;
}
var intData = PlayerPrefs.GetString(saveName + "." + "intDict");
if (!string.IsNullOrEmpty(intData))
{
var b = new BinaryFormatter();
var m = new MemoryStream(Convert.FromBase64String(intData));
intDict = b.Deserialize(m) as Dictionary<string, int>;
}
var boolData = PlayerPrefs.GetString(saveName + "." + "boolDict");
if (!string.IsNullOrEmpty(boolData))
{ {
PlayerPrefs.DeleteAll(); var b = new BinaryFormatter();
var m = new MemoryStream(Convert.FromBase64String(boolData));
boolDict = b.Deserialize(m) as Dictionary<string, bool>;
}
} }
/** /**
* Deletes a single stored variable. * Clears all stored variables.
*/ */
static public void DeleteKey(string key) public static void ClearAll()
{ {
PlayerPrefs.DeleteKey(AddPrefix(key)); stringDict.Clear();
intDict.Clear();
floatDict.Clear();
boolDict.Clear();
} }
/** /**
* Returns the float variable associated with the key. * Returns the float variable associated with the key.
*/ */
static public float GetFloat(string key) public static float GetFloat(string key)
{
if (String.IsNullOrEmpty(key) ||
!floatDict.ContainsKey(key))
{ {
return PlayerPrefs.GetFloat(AddPrefix(key)); return 0;
}
return floatDict[key];
} }
/** /**
* Returns the integer variable associated with the key. * Returns the integer variable associated with the key.
*/ */
static public int GetInteger(string key) public static int GetInteger(string key)
{
if (intDict == null)
{
Debug.Log ("Dict is null somehow");
}
if (String.IsNullOrEmpty(key) ||
!intDict.ContainsKey(key))
{ {
return PlayerPrefs.GetInt(AddPrefix(key)); return 0;
}
return intDict[key];
} }
/** /**
* Returns the boolean variable associated with the key. * Returns the boolean variable associated with the key.
*/ */
static public bool GetBoolean(string key) public static bool GetBoolean(string key)
{
if (String.IsNullOrEmpty(key) ||
!boolDict.ContainsKey(key))
{ {
return (bool)(PlayerPrefs.GetInt(AddPrefix(key)) != 0); return false;
}
return boolDict[key];
} }
/** /**
* Returns the string variable associated with the key. * Returns the string variable associated with the key.
*/ */
static public string GetString(string key) public static string GetString(string key)
{
if (String.IsNullOrEmpty(key) ||
!stringDict.ContainsKey(key))
{ {
return PlayerPrefs.GetString(AddPrefix(key)); return "";
} }
/** return stringDict[key];
* Returns true if a variable has been stored with this key.
*/
static public bool HasKey(string key)
{
return PlayerPrefs.HasKey(AddPrefix(key));
} }
/** /**
* Stores a float variable using the key. * Stores a float variable using the key.
*/ */
static public void SetFloat(string key, float value) public static void SetFloat(string key, float value)
{ {
PlayerPrefs.SetFloat(AddPrefix(key), value); floatDict[key] = value;
} }
/** /**
* Stores an integer variable using the key. * Stores an integer variable using the key.
*/ */
static public void SetInteger(string key, int value) public static void SetInteger(string key, int value)
{ {
PlayerPrefs.SetInt(AddPrefix(key), value); intDict[key] = value;
} }
/** /**
* Stores a boolean variable using the key. * Stores a boolean variable using the key.
*/ */
static public void SetBoolean(string key, bool value) public static void SetBoolean(string key, bool value)
{ {
PlayerPrefs.SetInt(AddPrefix(key), value ? 1 : 0); boolDict[key] = value;
} }
/** /**
* Stores a string variable using the key. * Stores a string variable using the key.
*/ */
static public void SetString(string key, string value) public static void SetString(string key, string value)
{ {
PlayerPrefs.SetString(AddPrefix(key), value); stringDict[key] = value;
} }
/** /**
* Replace keys in the input string with the string table entry. * Replace keys in the input string with the string table entry.
* Example format: "This {string_key} string" * Example format: "This {string_key} string"
*/ */
static public string SubstituteStrings(string text) public static string SubstituteStrings(string text)
{ {
string subbedText = text; string subbedText = text;
@ -146,7 +233,7 @@ namespace Fungus
* Chops a string at the first new line character encountered. * Chops a string at the first new line character encountered.
* This is useful for link / button strings that must fit on a single line. * This is useful for link / button strings that must fit on a single line.
*/ */
static public string FormatLinkText(string text) public static string FormatLinkText(string text)
{ {
string trimmed; string trimmed;
if (text.Contains("\n")) if (text.Contains("\n"))
@ -160,15 +247,5 @@ namespace Fungus
return trimmed; return trimmed;
} }
static string AddPrefix(string key)
{
if (saveName.Length == 0)
{
return key;
}
return saveName + "." + key;
}
} }
} }
Loading…
Cancel
Save