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. 185
      Assets/Fungus/Scripts/Variables.cs

26
Assets/Fungus/Scripts/Game.cs

@ -31,13 +31,6 @@ namespace Fungus
*/
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.
*/
@ -123,11 +116,6 @@ namespace Fungus
commandQueue.AddCommand(new Command.MoveToRoom(activeRoom));
commandQueue.Execute();
}
if (deleteVariables)
{
Variables.DeleteAll();
}
}
public virtual void Update()
@ -186,24 +174,24 @@ namespace Fungus
}
/**
* Save the current game variables to persistant storage.
* Store the currently loaded scene name so that Game.LoadGame() can automatically move to the appropriate scene.
* Save the current game variables to persistant storage using a save game name.
* 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.Save();
Variables.SetString("_scene", Application.loadedLevelName);
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.
* 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.
*/
public void LoadGame(string saveName = "_fungus")
{
Variables.SetSaveName(saveName);
Variables.Load(saveName);
string sceneName = Variables.GetString("_scene");
if (sceneName.Length > 0)
{

17
Assets/Fungus/Scripts/GameController.cs

@ -88,20 +88,11 @@ namespace Fungus
* Save the current game state to persistant storage.
* @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)
{
GameController.Save();
}
/**
* Saves the current game variables to persistant storage.
*/
public static void Save()
public static void Save(string saveName = "_fungus")
{
CommandQueue commandQueue = Game.GetInstance().commandQueue;
commandQueue.AddCommand(new Command.Call(delegate {
Game.GetInstance().SaveGame();
Game.GetInstance().SaveGame(saveName);
}));
}
@ -371,7 +362,9 @@ namespace Fungus
[Obsolete("Use Variables.DeleteKey() instead")]
public static void ClearValue(string key)
{
Variables.DeleteKey(key);
Variables.SetInteger(key, 0);
Variables.SetFloat(key, 0);
Variables.SetBoolean(key, false);
}
/**

185
Assets/Fungus/Scripts/Variables.cs

@ -1,128 +1,215 @@
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
namespace Fungus
{
/**
* Peristent data storage class for tracking game state.
* Provides a basic save game system.
* Static data storage class for managing global game variables.
* Provides save and load functionality for persistent storage between game sessions.
*/
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.
* You can use this to support multiple save data profiles, (e.g. for multiple users or a list of checkpoints).
* Save the variable dictionaries to persistent storage using a name tag.
*/
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 the variables state to persistent storage.
*/
static public void Save()
{
// Save ints
{
var b = new BinaryFormatter();
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();
}
/**
* 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)
{
PlayerPrefs.DeleteAll();
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))
{
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.
*/
static public float GetFloat(string key)
public static float GetFloat(string key)
{
return PlayerPrefs.GetFloat(AddPrefix(key));
if (String.IsNullOrEmpty(key) ||
!floatDict.ContainsKey(key))
{
return 0;
}
return floatDict[key];
}
/**
* Returns the integer variable associated with the key.
*/
static public int GetInteger(string key)
public static int GetInteger(string key)
{
return PlayerPrefs.GetInt(AddPrefix(key));
if (intDict == null)
{
Debug.Log ("Dict is null somehow");
}
if (String.IsNullOrEmpty(key) ||
!intDict.ContainsKey(key))
{
return 0;
}
return intDict[key];
}
/**
* Returns the boolean variable associated with the key.
*/
static public bool GetBoolean(string key)
public static bool GetBoolean(string key)
{
return (bool)(PlayerPrefs.GetInt(AddPrefix(key)) != 0);
if (String.IsNullOrEmpty(key) ||
!boolDict.ContainsKey(key))
{
return false;
}
return boolDict[key];
}
/**
* Returns the string variable associated with the key.
*/
static public string GetString(string key)
public static string GetString(string key)
{
return PlayerPrefs.GetString(AddPrefix(key));
}
if (String.IsNullOrEmpty(key) ||
!stringDict.ContainsKey(key))
{
return "";
}
/**
* Returns true if a variable has been stored with this key.
*/
static public bool HasKey(string key)
{
return PlayerPrefs.HasKey(AddPrefix(key));
return stringDict[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.
*/
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.
*/
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.
*/
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.
* Example format: "This {string_key} string"
*/
static public string SubstituteStrings(string text)
public static string SubstituteStrings(string text)
{
string subbedText = text;
@ -146,7 +233,7 @@ namespace Fungus
* Chops a string at the first new line character encountered.
* 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;
if (text.Contains("\n"))
@ -160,15 +247,5 @@ namespace Fungus
return trimmed;
}
static string AddPrefix(string key)
{
if (saveName.Length == 0)
{
return key;
}
return saveName + "." + key;
}
}
}
Loading…
Cancel
Save