I realize this question is a year old, but there are still 27 people following the question and I think I found a neat solution!
Basically I use dictionaries to store variables of the same type. They can be accessed in a similar way PlayerPrefs does this:
mySaves.SetInt("VariableName", 23);
int i = mySaves.GetInt("VariableName");
My starting point was the Unity tutorial mentioned in the question. All I added were functions to convert the dictionaries to strings and vice versa and some checks whether the variable you want exists. I also made sure that exeptions when trying to read your save file are handled and added code to use the PlayerPrefs instead, when the game is run in the WebPlayer.
This is how my save controller looks now:
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
public class SaveController : MonoBehaviour {
public static SaveController control;
public string fileName = "myGame.save";
private Dictionary<string, int> ints;
private Dictionary<string, string> strings;
private SaveGame save;
private bool writeSave = false;
private BinaryFormatter formatter;
private void Awake ()
{
if (control != null && control != this)
{
Destroy(gameObject);
return;
}
DontDestroyOnLoad(gameObject);
control = this;
formatter = new BinaryFormatter();
if(!Load())
save = new SaveGame();
}
private bool Load()
{
if (Application.isWebPlayer)
{
// Everything is in PlayerPrefs and doesn't have to be loaded
Debug.Log("Loading everything from PlayerPrefs");
return true;
}
else if(File.Exists(Application.persistentDataPath + "/"+fileName))
{
Debug.Log ("Loading " + Application.persistentDataPath + "/"+fileName);
// Load File
FileStream file = File.Open(Application.persistentDataPath + "/"+fileName, FileMode.Open);
try
{
save = (SaveGame)formatter.Deserialize(file);
}
catch
{
Debug.LogWarning("Couldn't deserialize SaveGame. Creating new!");
save = new SaveGame();
}
file.Close();
ints = StringToIntDict(save.ints);
strings = StringToStringDict(save.strings);
return true;
}
else
{
Debug.Log ("No Saves found.");
return false;
}
}
private void Save()
{
if (Application.isWebPlayer)
{
// Everything is in PlayerPrefs and doesn't have to written to file
Debug.LogWarning("This is a WebPlayer! I shouldn't even be called!");
}
else
{
// Save dictionaries
save.strings = StringDictToString(strings);
save.ints = IntDictToString(ints);
// Write to file
FileStream file = File.Create(Application.persistentDataPath + "/" + fileName);
formatter.Serialize(file, save);
file.Close();
}
}
public void Reset()
{
if (Application.isWebPlayer)
{
PlayerPrefs.DeleteAll();
Debug.Log("Deleted PlayerPrefs");
}
else
{
ints.Clear();
strings.Clear();
save = new SaveGame();
Debug.Log("Reset SaveGame");
}
}
private void LateUpdate()
{
if(writeSave)
{
Save();
writeSave = false;
}
}
public void SetString(string id, string value)
{
if (Application.isWebPlayer)
{
PlayerPrefs.SetString(id, value);
}
else
{
strings[id] = value;
writeSave = true;
}
}
public string GetString(string id)
{
if (Application.isWebPlayer)
{
return PlayerPrefs.HasKey(id) ? PlayerPrefs.GetString(id) : "";
}
else
{
return strings.ContainsKey(id) ? strings[id] : "";
}
}
public void SetInt(string id, int value)
{
if (Application.isWebPlayer)
{
PlayerPrefs.SetInt(id, value);
}
else
{
ints[id] = value;
writeSave = true;
}
}
public int GetInt(string id)
{
if (Application.isWebPlayer)
{
return PlayerPrefs.HasKey(id) ? PlayerPrefs.GetInt(id) : 0;
}
else
{
return ints.ContainsKey(id) ? ints[id] : 0;
}
}
private Dictionary<string, int> StringToIntDict(string s)
{
Dictionary<string, int> dict = new Dictionary<string, int>();
if (s == null)
{
Debug.LogWarning("Could not create dictionary, because string is null!");
return dict;
}
string[] tokens = s.Split(new char[] { ':', ',' }, StringSplitOptions.RemoveEmptyEntries);
// Walk through each item
for (int i = 0; i < tokens.Length; i += 2)
{
dict.Add(tokens*, int.Parse(tokens[i + 1]));*
}
//Debug.Log(“Loaded " + dict.Count + " ints”);
return dict;
}
private Dictionary<string, string> StringToStringDict(string s)
{
Dictionary<string, string> dict = new Dictionary<string, string>();
if (s == null)
{
Debug.LogWarning(“Could not create dictionary, because string is null!”);
return dict;
}
string[] tokens = s.Split(new char[] { ‘:’, ‘,’ }, StringSplitOptions.RemoveEmptyEntries);
// Walk through each item
for (int i = 0; i < tokens.Length; i += 2)
{
dict.Add(tokens*, tokens[i + 1]);*
}
//Debug.Log(“Loaded " + dict.Count + " strings”);
return dict;
}
private string IntDictToString(Dictionary<string, int> d)
{
string result = “”;
foreach (KeyValuePair<string, int> pair in d)
{
result += pair.Key + “:” + pair.Value + “,”;
}
// Remove the final delimiter
result = result.TrimEnd(‘,’);
return result;
}
private string StringDictToString(Dictionary<string, string> d)
{
string result = “”;
foreach (KeyValuePair<string, string> pair in d)
{
result += pair.Key + “:” + pair.Value + “,”;
}
// Remove the final delimiter
result = result.TrimEnd(‘,’);
return result;
}
}
[Serializable]
class SaveGame
{
public string strings = “”;
public string ints = “”;
}