Advertisement
Tkrain42

SavingSystem For JSon.NetForUnity

May 13th, 2021
770
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.07 KB | None | 0 0
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using Newtonsoft.Json;
  6. using UnityEngine;
  7. using UnityEngine.SceneManagement;
  8.  
  9. namespace GameDevTV.Saving
  10. {
  11.     /// <summary>
  12.     /// This component provides the interface to the saving system. It provides
  13.     /// methods to save and restore a scene.
  14.     ///
  15.     /// This component should be created once and shared between all subsequent scenes.
  16.     /// </summary>
  17.     public class SavingSystem : MonoBehaviour
  18.     {
  19.         /// <summary>
  20.         /// Will load the last scene that was saved and restore the state. This
  21.         /// must be run as a coroutine.
  22.         /// </summary>
  23.         /// <param name="saveFile">The save file to consult for loading.</param>
  24.         public IEnumerator LoadLastScene(string saveFile)
  25.         {
  26.             Dictionary<string, object> state = LoadFile(saveFile);
  27.             int buildIndex = SceneManager.GetActiveScene().buildIndex;
  28.             if (state.ContainsKey("lastSceneBuildIndex"))
  29.             {
  30.                 buildIndex = state["lastSceneBuildIndex"].ToInt();
  31.             }
  32.             yield return SceneManager.LoadSceneAsync(buildIndex);
  33.             RestoreState(state);
  34.         }
  35.  
  36.         /// <summary>
  37.         /// Save the current scene to the provided save file.
  38.         /// </summary>
  39.         public void Save(string saveFile)
  40.         {
  41.             Dictionary<string, object> state = LoadFile(saveFile);
  42.             CaptureState(state);
  43.             SaveFile(saveFile, state);
  44.         }
  45.  
  46.         /// <summary>
  47.         /// Delete the state in the given save file.
  48.         /// </summary>
  49.         public void Delete(string saveFile)
  50.         {
  51.             File.Delete(GetPathFromSaveFile(saveFile));
  52.         }
  53.  
  54.         public void Load(string saveFile)
  55.         {
  56.             RestoreState(LoadFile(saveFile));
  57.         }
  58.  
  59.         // PRIVATE
  60.  
  61.         private Dictionary<string, object> LoadFile(string saveFile)
  62.         {
  63.             string path = GetPathFromSaveFile(saveFile);
  64.             if (!File.Exists(path))
  65.             {
  66.                 return new Dictionary<string, object>();
  67.             }
  68.  
  69.             using (StreamReader file = File.OpenText(path))
  70.             {
  71.                 JsonSerializer serializer = new JsonSerializer();
  72.                 serializer.TypeNameHandling = TypeNameHandling.All;
  73.                 serializer.Formatting = Formatting.Indented;
  74.                 serializer.FloatParseHandling = FloatParseHandling.Double;
  75.  
  76.                 return (Dictionary<string, object>) serializer.Deserialize(file, typeof(Dictionary<string, object>));
  77.             }
  78.  
  79.  
  80.             //using (FileStream stream = File.Open(path, FileMode.Open))
  81.             //{
  82.             //    BinaryFormatter formatter = new BinaryFormatter();
  83.             //    return (Dictionary<string, object>)formatter.Deserialize(stream);
  84.             //}
  85.         }
  86.  
  87.         private void SaveFile(string saveFile, object state)
  88.         {
  89.             string path = GetPathFromSaveFile(saveFile);
  90.             print("Saving to " + path);
  91.  
  92.             using (StreamWriter file = File.CreateText(path))
  93.             {
  94.                 JsonSerializer serializer = new JsonSerializer();
  95.                 serializer.TypeNameHandling = TypeNameHandling.All;
  96.                 serializer.Formatting = Formatting.Indented;
  97.                 serializer.FloatParseHandling = FloatParseHandling.Double;
  98.                 serializer.Serialize(file, state);
  99.             }
  100.             //using (FileStream stream = File.Open(path, FileMode.Create))
  101.             //{
  102.             //    BinaryFormatter formatter = new BinaryFormatter();
  103.             //    formatter.Serialize(stream, state);
  104.             //}
  105.         }
  106.  
  107.         private void CaptureState(Dictionary<string, object> state)
  108.         {
  109.             foreach (SaveableEntity saveable in FindObjectsOfType<SaveableEntity>())
  110.             {
  111.                 state[saveable.GetUniqueIdentifier()] = saveable.CaptureState();
  112.             }
  113.  
  114.             state["lastSceneBuildIndex"] = SceneManager.GetActiveScene().buildIndex;
  115.         }
  116.  
  117.         private void RestoreState(Dictionary<string, object> state)
  118.         {
  119.             foreach (SaveableEntity saveable in FindObjectsOfType<SaveableEntity>())
  120.             {
  121.                 string id = saveable.GetUniqueIdentifier();
  122.                 if (state.ContainsKey(id))
  123.                 {
  124.                     saveable.RestoreState(state[id]);
  125.                 }
  126.             }
  127.         }
  128.  
  129.         private string GetPathFromSaveFile(string saveFile)
  130.         {
  131.             return Path.Combine(Application.persistentDataPath, saveFile + ".json");
  132.         }
  133.     }
  134.  
  135.     public static class SavingHelpers
  136.     {
  137.         /// <summary>
  138.         /// Converts an object that has been decoded by JSon.Net For Unity into a float.  Will succeed if the object was deserialized as a double, float, or int64
  139.         /// </summary>
  140.         /// <param name="o">object that has been deserialized by Json.Net For Unity</param>
  141.         /// <returns></returns>
  142.         public static float ToFloat(this object o)
  143.         {
  144.             switch (o)
  145.             {
  146.                 case double d: return (float) d;
  147.                 case float f: return f;
  148.                 case int i: return i;
  149.                 case Int64 q: return (float) q;
  150.                 default: return 0.0f;
  151.             }
  152.         }
  153.         /// <summary>
  154.         /// Converts an object that has been decoded by JSon.Net For Unity into an int.  Will succeed if the object was deserialized as a double, float, or int64.
  155.         /// Float and double values will be truncated automatically.
  156.         /// </summary>
  157.         /// <param name="o">object that has been deserialized by Json.Net For Unity</param>
  158.         /// <returns></returns>
  159.         public static int ToInt(this object o)
  160.         {
  161.             switch (o)
  162.             {
  163.                 case double d: return Mathf.FloorToInt((float) d);
  164.                 case float f: return Mathf.FloorToInt(f);
  165.                 case int i: return i;
  166.                 case Int64 q: return (int) q;
  167.                 default: return 0;
  168.             }
  169.         }
  170.         /// <summary>
  171.         /// Returns an object for JSon.Net for Unity to Serialize.  
  172.         /// </summary>
  173.         /// <param name="v"></param>
  174.         /// <returns></returns>
  175.         public static object ToObject(this Vector3 v)
  176.         {
  177.             return new List<float> { v.x, v.y, v.z};
  178.         }
  179.         /// <summary>
  180.         /// Converts and object that was deserialized as a Vector3 by JSon.Net to a bonafide Vector3.
  181.         /// </summary>
  182.         /// <param name="o"></param>
  183.         /// <returns></returns>
  184.         public static Vector3 ToVector3(this object o)
  185.         {
  186.             Vector3 v = Vector3.zero;
  187.             if (o is IList l)
  188.             {
  189.                 if (l.Count == 3)
  190.                 {
  191.                     v.x = l[0].ToFloat();
  192.                     v.y = l[1].ToFloat();
  193.                     v.z = l[2].ToFloat();
  194.                 }
  195.             }
  196.             return v;
  197.         }
  198.     }
  199. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement