PlayerPrefs for Lightweight Storage
Unity's built-in key-value store suits preferences and small settings.
// Write values
PlayerPrefs.SetString("Username", activeUser);
PlayerPrefs.SetInt("HighScore", bestScore);
PlayerPrefs.SetFloat("MusicVolume", masterVolume);
// Retrieve values
activeUser = PlayerPrefs.GetString("Username", "Guest");
bestScore = PlayerPrefs.GetInt("HighScore", 0);
masterVolume = PlayerPrefs.GetFloat("MusicVolume", 1.0f);
// Remove specific entry
PlayerPrefs.DeleteKey("HighScore");
// Purge everything
PlayerPrefs.DeleteAll();
// Force immediate disk write
PlayerPrefs.Save();
Binary Serialization with BinaryFormatter
For complex objects, a binary format reduces file size and discourages manual editing. Because BinaryFormatter cannot directly handle Unity value types like Vector3, a serializable DTO bridges the gap.
Define the runtime and data transfer objects:
[System.Serializable]
public class Avatar
{
public int vitality;
public int energy;
public Vector3 worldPos;
}
[System.Serializable]
public class AvatarSnapshot
{
public int vitality;
public int energy;
public float[] coords;
public AvatarSnapshot(Avatar source)
{
vitality = source.vitality;
energy = source.energy;
coords = new float[3];
coords[0] = source.worldPos.x;
coords[1] = source.worldPos.y;
coords[2] = source.worldPos.z;
}
}
Static helper for disk operations:
public static class BinaryDataStore
{
public static void StoreAvatar(Avatar target)
{
var formatter = new BinaryFormatter();
var destination = Path.Combine(Application.persistentDataPath, "avatar.bin");
using (var fs = new FileStream(destination, FileMode.Create))
{
var snapshot = new AvatarSnapshot(target);
formatter.Serialize(fs, snapshot);
}
}
public static AvatarSnapshot RetrieveAvatar()
{
var source = Path.Combine(Application.persistentDataPath, "avatar.bin");
if (!File.Exists(source))
{
Debug.LogError($"No saved data at {source}");
return null;
}
var formatter = new BinaryFormatter();
using (var fs = new FileStream(source, FileMode.Open))
{
return formatter.Deserialize(fs) as AvatarSnapshot;
}
}
}
JSON Text Serialization via JsonUtility
JSON offers human-readable saves and easy external editing. Unity's JsonUtility handles plain C# objects quick.
[System.Serializable]
public class ShipConfiguration
{
public int hullIntegrity;
public float shieldPower;
public string vesselClass;
}
public static class JsonDataStore
{
public static void StoreShipState(ShipConfiguration vessel)
{
var route = Path.Combine(Application.persistentDataPath, "ship.json");
var payload = JsonUtility.ToJson(vessel, true);
File.WriteAllText(route, payload);
}
public static ShipConfiguration RestoreShipState()
{
var route = Path.Combine(Application.persistentDataPath, "ship.json");
if (!File.Exists(route))
{
Debug.LogError($"Missing save file: {route}");
return null;
}
var payload = File.ReadAllText(route);
return JsonUtility.FromJson<ShipConfiguration>(payload);
}
}
XML Serialization with XmlSerializer
XML remains useful when schema readability or external tool consumption matters. Insure target classes expose parameterless constructors and public fields.
public class CrewMember
{
public CrewMember() { }
public CrewMember(string id, string division)
{
codename = id;
unit = division;
}
public string codename;
public string unit;
}
Read and write operations:
var rosterPath = Path.Combine(Application.persistentDataPath, "crew.xml");
List<CrewMember> roster = null;
// Loading
var xmlConverter = new XmlSerializer(typeof(List<CrewMember>));
using (var reader = new StreamReader(rosterPath))
{
roster = xmlConverter.Deserialize(reader) as List<CrewMember>;
}
// Saving
using (var writer = new StreamWriter(rosterPath))
{
xmlConverter.Serialize(writer, roster);
}
Resulting file srtucture:
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfCrewMember xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<CrewMember>
<codename>Viper</codename>
<unit>Navigation</unit>
</CrewMember>
<CrewMember>
<codename>Rook</codename>
<unit>Engineering</unit>
</CrewMember>
</ArrayOfCrewMember>