TIP: Correct Save/Load ScriptedObjects as Resources

Discussion and help for Easy Save 3
Post Reply
vitorbalbio
Posts: 3
Joined: Wed Aug 03, 2016 2:35 pm

TIP: Correct Save/Load ScriptedObjects as Resources

Post by vitorbalbio »

Hi
The usual use of scripted Objects is as Data and used as a database system. For this the default implementation in EasySave do not work since it's referenced by scene and lose the reference if you try to save/load the save data from another scene or making you use a static cache during all the game for every single scripted object possible to use. I managed to get around it manually changing the code generated. Check this sample that i'm using in a card game. Saving the name/path of the scripted object instead of the object itself you fix this. So i let here a suggestions to developers, put a checkbox per attribute in the EasySave Types panel to use "reference to resources/disk" if a object is a scripted object and handle it all by default.

Check the sample:

Code: Select all

public void SaveToDisk() {
        ES3.Save<List<CardAndQtd>>("library", library);
    }

    public void LoadFromDisk() {
        library = ES3.Load<List<CardAndQtd>>("library");        
    }

Code: Select all

using System;
using UnityEngine;

namespace ES3Types
{
	[UnityEngine.Scripting.Preserve]
	[ES3PropertiesAttribute("card", "qtd")]
	public class ES3Type_CardAndQtd : ES3ObjectType
	{
		public static ES3Type Instance = null;

		public ES3Type_CardAndQtd() : base(typeof(CardAndQtd)){ Instance = this; }

		protected override void WriteObject(object obj, ES3Writer writer)
		{
			var instance = (CardAndQtd)obj;

            writer.WriteProperty("card", instance.card.name, ES3Type_string.Instance);
            writer.WriteProperty("qtd", instance.qtd, ES3Type_int.Instance);
		}

		protected override void ReadObject<T>(ES3Reader reader, object obj)
		{
			var instance = (CardAndQtd)obj;
			foreach(string propertyName in reader.Properties)
			{
				switch(propertyName)
				{
					
					case "card":
                        string path = "Data/Cards/";
                        instance.card = Resources.Load<Model_Card>(path + reader.Read<System.String>(ES3Type_string.Instance));
                        Debug.Log(instance.card);
                        break;
					case "qtd":
						instance.qtd = reader.Read<System.Int32>(ES3Type_int.Instance);
						break;
					default:
						reader.Skip();
						break;
				}
			}
		}

		protected override object ReadObject<T>(ES3Reader reader)
		{
			var instance = new CardAndQtd();
			ReadObject<T>(reader, instance);
			return instance;
		}
	}

	public class ES3Type_CardAndQtdArray : ES3ArrayType
	{
		public static ES3Type Instance;

		public ES3Type_CardAndQtdArray() : base(typeof(CardAndQtd[]), ES3Type_CardAndQtd.Instance)
		{
			Instance = this;
		}
	}
}

User avatar
Joel
Moodkie Staff
Posts: 2755
Joined: Wed Nov 07, 2012 10:32 pm

Re: TIP: Correct Save/Load ScriptedObjects as Resources

Post by Joel »

Hi there,

As fields of ScriptableObject are reference types, they are stored by reference. Note however that if you save the ScriptableObject directly using ES3.Save, it will be stored by value as this will refer to the value.

All the best,
Joel
Joel @ Moodkie Interactive
Twitter - Unity

Post Reply