Different refference ids between scenes

Discussion and help for Easy Save 3
Post Reply
heraldoagnese
Posts: 1
Joined: Sun May 21, 2023 4:13 pm

Different refference ids between scenes

Post by heraldoagnese »

Hi! Thanks for this very usefull package, it saved me a lot of time, but I'm having a problem when I reference the same scriptable object between two different scenes. I have created an abstract class called PersistentData that inherits from ScriptableObject, wich uses the load/save system from ES3 to save all field of its heir, for example (ScriptableObject -> PersistentData -> PlayerData).

So everything works good when I store primitive types but the problem appears when I serialize a ScriptableObject, it loads at the first scene but then when I change the scene the serialized field gets None, no matter if I refresh and optimize the ES3 Reference Mgr or if I type manually the ids in every scene it always do the same.
Anyways for a hotfix to our issue I've commented the refresh method of the ES3 Reference Mgr and I've created a prefab that I update manually in an isolated scene just for adding the references and then I used it in every scene with the same ids, but it would be great to store all my references into an array in wich I can add and delete them because all that I need to store are some types that inherit from scriptable objects for example WeaponType that is a ScriptableObject with no fields just for comparison purposes. Thanks very much in advance!

Code: Select all

public abstract class PersistentData : ScriptableObject
{
    public void Save()
    {
        var settings = new ES3Settings { memberReferenceMode = ES3.ReferenceMode.ByRefAndValue };
        ES3.Save(name, this, settings);
    }

    public virtual void Load()
    {
        if (ES3.KeyExists(name))
        {
            ES3.LoadInto(name, this);
        }
    }

    public void DropData()
    {
        ResetData();
        Save();
    }

    public abstract void ResetData();
}

Code: Select all

[CreateAssetMenu(fileName = "Player Data", menuName = "Core/PlayerData")]
public class PlayerData : PersistentData
{
    public int expLevel = 0;
    public float exp = 0;
    public int balance = 0;
    public int previousExpLevel = 0;
    public float previousExp = 0;
    public WeaponType selectedWeapon;
    public SkinType selectedSkin;

    public override void ResetData()
    {
        expLevel = 0;
        exp = 0;
        previousExp = 0;
        previousExpLevel = 0;
        balance = 0;
    }
}

Code: Select all

[CreateAssetMenu(menuName = "Types/Weapons")]
public class WeaponType : ScriptableObject { }

Code: Select all

namespace ES3Types
{
	[UnityEngine.Scripting.Preserve]
	[ES3PropertiesAttribute("expLevel", "exp", "balance", "previousExpLevel", "previousExp", "selectedWeapon", "selectedSkin")]
	public class ES3UserType_PlayerData : ES3ScriptableObjectType
	{
		public static ES3Type Instance = null;

		public ES3UserType_PlayerData() : base(typeof(PlayerData)){ Instance = this; priority = 1; }


		protected override void WriteScriptableObject(object obj, ES3Writer writer)
		{
			var instance = (PlayerData)obj;
			
			writer.WriteProperty("expLevel", instance.expLevel, ES3Type_int.Instance);
			writer.WriteProperty("exp", instance.exp, ES3Type_float.Instance);
			writer.WriteProperty("balance", instance.balance, ES3Type_int.Instance);
			writer.WriteProperty("previousExpLevel", instance.previousExpLevel, ES3Type_int.Instance);
			writer.WriteProperty("previousExp", instance.previousExp, ES3Type_float.Instance);
			writer.WritePropertyByRef("selectedWeapon", instance.selectedWeapon);
			writer.WritePropertyByRef("selectedSkin", instance.selectedSkin);
		}

		protected override void ReadScriptableObject<T>(ES3Reader reader, object obj)
		{
			var instance = (PlayerData)obj;
			foreach(string propertyName in reader.Properties)
			{
				switch(propertyName)
				{
					
					case "expLevel":
						instance.expLevel = reader.Read<System.Int32>(ES3Type_int.Instance);
						break;
					case "exp":
						instance.exp = reader.Read<System.Single>(ES3Type_float.Instance);
						break;
					case "balance":
						instance.balance = reader.Read<System.Int32>(ES3Type_int.Instance);
						break;
					case "previousExpLevel":
						instance.previousExpLevel = reader.Read<System.Int32>(ES3Type_int.Instance);
						break;
					case "previousExp":
						instance.previousExp = reader.Read<System.Single>(ES3Type_float.Instance);
						break;
					case "selectedWeapon":
						instance.selectedWeapon = reader.Read<WeaponType>();
						break;
					case "selectedSkin":
						instance.selectedSkin = reader.Read<SkinType>();
						break;
					default:
						reader.Skip();
						break;
				}
			}
		}
	}


	public class ES3UserType_PlayerDataArray : ES3ArrayType
	{
		public static ES3Type Instance;

		public ES3UserType_PlayerDataArray() : base(typeof(PlayerData[]), ES3UserType_PlayerData.Instance)
		{
			Instance = this;
		}
	}
}
ImageImage
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Different refference ids between scenes

Post by Joel »

Hi there,

Is your ScriptableObject a dependency of the scene you are loading in? It's not possible to load a reference to something which doesn't exist.

Also is your ScriptableObject created at runtime, or does it exist outside of the scene prior to runtime (i.e. a ScriptableObject in your project folder).

If this doesn't resolve the issue, please could you create a new project with a simple scene which replicates the issue and private message it to me with instructions so I can see what is happening.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Post Reply