Scriptable Object variable value is being removed when loading

Discussion and help for Easy Save 3
robotSmith
Posts: 39
Joined: Thu Apr 01, 2021 4:53 pm

Re: Scriptable Object variable value is being removed when loading

Post by robotSmith »

Hello.

There is no "Assets/Easy Save 3/Types/", only "Assets/Easy Save 3/Scripts/Types/". I imagine that's not the one you need.

I think my main questions are:
1. I was not expecting ES3 touching files that I'm not directly saving, and I'm assuming is touching the file because a variable is being discarded on Load (I probably just don't understand how it really works).
2. Why would this happen with one object but not another object of the same kind (specially if the variable is being set on the inspector). I attached a video showing that.

The variable that is being discarded is "ContainerType" on the Ceramic Container. Coconut Container works fine. (I was able to reproduce this in a small project if that's helpful)

This is the .es3 save file

Code: Select all

{
	"ItemDatabase" : {
		"__type" : "System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[IItem, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]],mscorlib",
		"value" : {"Ceramic Container":{
				"__type" : "PortableContainer,Assembly-CSharp",
				"_ES3Ref" : "7106626596454675402",
				"_ES3Ref" : "7106626596454675402",
				"resourceToHold" : null,
				"containerType" : {
					"_ES3Ref" : "8130308086468330343"
				},
				"itemTitle" : "Ceramic Container"
			},"Coconut Container":{
				"__type" : "PortableContainer,Assembly-CSharp",
				"_ES3Ref" : "8459430624397898974",
				"_ES3Ref" : "8459430624397898974",
				"resourceToHold" : {
					"_ES3Ref" : "7280631713494607686"
				},
				"containerType" : {
					"_ES3Ref" : "878180826301136058"
				},
				"itemTitle" : "Coconut Container"
			}
		}
	}
}
This is the (now simple) save file:

Code: Select all


public class ItemDatabase : MonoBehaviour
{
#pragma warning disable 649
    [SerializeField] Item[] items;
#pragma warning restore 649

    public static Dictionary<string, IItem> ItemDictionary { get; private set; }

    private void Awake()
    {
        CreateItemDatabase();
    }

    private void Update()
    {
        if (Input.GetKeyUp(KeyCode.S))
        {
            SaveDatabaseWithNewItems();
        }
        if (Input.GetKeyUp(KeyCode.L))
        {
            Load();
        }
    }

    private void CreateItemDatabase()
    {
        ItemDictionary = new Dictionary<string, IItem>();

        int counter = items.Length;

        for (int i = 0; i < counter; i++)
        {
            Assert.IsTrue(items[i], "Item is arriving null, probably an empty space in the array");
            Assert.IsFalse(ItemDictionary.ContainsKey(items[i].ItemID), "Repeated item ID: " + items[i].ItemID + ", " + items[i].name);
            ItemDictionary.Add(items[i].ItemID, items[i]);
        }
        Debug.Log("Dictionary created");
    }


    private void SaveDatabaseWithNewItems()
    {
        ES3.Save<Dictionary<string, IItem>>("ItemDatabase", ItemDictionary);
        ItemDictionary = ES3.Load<Dictionary<string, IItem>>("ItemDatabase");
        Debug.Log("Saving");
    }


    private void Load()
    {
        Debug.Log("Load Database");
        ItemDictionary = ES3.Load<Dictionary<string, IItem>>("ItemDatabase");
        //LoadSprites();
        ItemDictionary = ES3.Load<Dictionary<string, IItem>>("ItemDatabase");
    }
}
Attachments
SaveTest.mp4
(1.37 MiB) Downloaded 101 times
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Scriptable Object variable value is being removed when loading

Post by Joel »

Hi there,

If you're able to replicate this in a new project with minimal logic, please could you private message it to me?

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
robotSmith
Posts: 39
Joined: Thu Apr 01, 2021 4:53 pm

Re: Scriptable Object variable value is being removed when loading

Post by robotSmith »

Thanks Joel! Sent
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Scriptable Object variable value is being removed when loading

Post by Joel »

Hi there,

Thanks for sending that over. As mentioned previously, the issue is that Unity is creating a new instance of your ScriptableObject at runtime which will no longer exist when you exit the scene. This usually happens when you're modifying the ScriptableObject, so Unity has to create an instance to ensure that no permanent changes are made to the ScriptableObject in Assets while you're in play mode.

As this is part of Unity's functionality, you would need to contact them for clarification on why this is happening in your project. A possible workaround however would be to save your ContainerType separately to ensure that it's saved and loaded by value rather than by reference. This way the reference will always exist.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
robotSmith
Posts: 39
Joined: Thu Apr 01, 2021 4:53 pm

Re: Scriptable Object variable value is being removed when loading

Post by robotSmith »

Thanks Joel for looking into it.
Joel wrote: Tue Jun 08, 2021 8:32 am This usually happens when you're modifying the ScriptableObject, so Unity has to create an instance to ensure that no permanent changes are made to the ScriptableObject in Assets while you're in play mode.
I think you are explaining the opposite. Scriptable Objects always keep the data that was changed on Play mode to the asset (compared to MonoBehaviours that do not).

But anyway, the problem seems to be that there is a new instance on Play.
- How were you able to test this and understand that the problem is a new instance? Maybe I can check this to be able to send a msg to Unity.
- From your experience, how common is this? If this is common it would be very painful to have to save every object that exists in the file system already so they are saved by value :( .
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Scriptable Object variable value is being removed when loading

Post by Joel »

Hi there,

Looking deeper into this it looks like there's now a way we can force Unity to keep the same reference ID, and is something I can build into the reference manager so that this requires no effort on your part.

I've created a version of Easy Save which does this. If you private message me your invoice number I'll send it over.

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