Saving Wrapper Script
using System.Collections;
using RPG.Saving;
using UnityEngine;
namespace RPG.SceneManagement
{
public class SavingWrapper : MonoBehaviour
{
const string defaultSaveFile = "saveFile";
[SerializeField] float fadeInTime = 0.2f;
private void Awake()
{
StartCoroutine(LoadLastScene());
}
private IEnumerator LoadLastScene() {
//yield return GetComponent<SavingSystem>().LoadLastScene(defaultSaveFile);
Fader fader = FindObjectOfType<Fader>();
fader.FadeOutImmediate();
yield return fader.FadeIn(fadeInTime);
}
private void Update() {
if (Input.GetKeyDown(KeyCode.S))
{
Save();
}
if (Input.GetKeyDown(KeyCode.L))
{
Load();
}
if (Input.GetKeyDown(KeyCode.Delete))
{
Delete();
}
}
public void Load()
{
StartCoroutine(GetComponent<SavingSystem>().LoadLastScene(defaultSaveFile));
}
public void Save()
{
GetComponent<SavingSystem>().Save(defaultSaveFile);
}
public void Delete()
{
GetComponent<SavingSystem>().Delete(defaultSaveFile);
}
}
}
Saving System Script
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace RPG.Saving
{
/// <summary>
/// This component provides the interface to the saving system. It provides
/// methods to save and restore a scene.
///
/// This component should be created once and shared between all subsequent scenes.
/// </summary>
public class SavingSystem : MonoBehaviour
{
/// <summary>
/// Will load the last scene that was saved and restore the state. This
/// must be run as a coroutine.
/// </summary>
/// <param name="saveFile">The save file to consult for loading.</param>
public IEnumerator LoadLastScene(string saveFile)
{
Dictionary<string, object> state = LoadFile(saveFile);
int buildIndex = SceneManager.GetActiveScene().buildIndex;
if (state.ContainsKey("lastSceneBuildIndex"))
{
buildIndex = (int)state["lastSceneBuildIndex"];
}
yield return SceneManager.LoadSceneAsync(buildIndex);
RestoreState(state);
}
/// <summary>
/// Save the current scene to the provided save file.
/// </summary>
public void Save(string saveFile)
{
Dictionary<string, object> state = LoadFile(saveFile);
CaptureState(state);
SaveFile(saveFile, state);
}
/// <summary>
/// Delete the state in the given save file.
/// </summary>
public void Delete(string saveFile)
{
File.Delete(GetPathFromSaveFile(saveFile));
}
// PRIVATE
private void Load(string saveFile)
{
RestoreState(LoadFile(saveFile));
}
private Dictionary<string, object> LoadFile(string saveFile)
{
string path = GetPathFromSaveFile(saveFile);
if (!File.Exists(path))
{
return new Dictionary<string, object>();
}
using (FileStream stream = File.Open(path, FileMode.Open))
{
BinaryFormatter formatter = new BinaryFormatter();
return (Dictionary<string, object>)formatter.Deserialize(stream);
}
}
private void SaveFile(string saveFile, object state)
{
string path = GetPathFromSaveFile(saveFile);
print("Saving to " + path);
using (FileStream stream = File.Open(path, FileMode.Create))
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, state);
}
}
private void CaptureState(Dictionary<string, object> state)
{
foreach (SaveableEntity saveable in FindObjectsOfType<SaveableEntity>())
{
state[saveable.GetUniqueIdentifier()] = saveable.CaptureState();
}
state["lastSceneBuildIndex"] = SceneManager.GetActiveScene().buildIndex;
}
private void RestoreState(Dictionary<string, object> state)
{
foreach (SaveableEntity saveable in FindObjectsOfType<SaveableEntity>())
{
string id = saveable.GetUniqueIdentifier();
if (state.ContainsKey(id))
{
saveable.RestoreState(state[id]);
}
}
}
private string GetPathFromSaveFile(string saveFile)
{
return Path.Combine(Application.persistentDataPath, saveFile + ".sav");
}
}
}