Reference manager destroyed before other objects when stopping execution

Discussion and help for Easy Save 3
Post Reply
r4scar_capac
Posts: 4
Joined: Mon Mar 14, 2022 3:28 pm

Reference manager destroyed before other objects when stopping execution

Post by r4scar_capac »

Hello,

In order to have persistence between scenes, my ES3.Save() are called in OnDestroy(), in several scripts. But when I quit playmode or Alt+F4 in a build, sometimes an "InvalidOperationException" error will occur, pretty randomly.

My reference manager is a child of an AppManager, on which I'm calling a DontDestroyOnLoad(). While debugging, I figured that some ES3.Save() are called after the AppManager has been destroyed.

How can I ensure that the reference manager is available for every save when the game is being quit? Thanks!
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Reference manager destroyed before other objects when stopping execution

Post by Joel »

Hi there, and thanks for getting in contact.

I’ve not heard of this happening before. OnDestroy should be called for all objects before they are actually destroyed (I.e. they are only marked for destruction at this point, see https://docs.unity3d.com/ScriptReferenc ... stroy.html).

Are you able to replicate this in a new project with a simple scene? Could you also send me the full error message for the exception you’re receiving?

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
r4scar_capac
Posts: 4
Joined: Mon Mar 14, 2022 3:28 pm

Re: Reference manager destroyed before other objects when stopping execution

Post by r4scar_capac »

Hey, thanks for your quick reply and sorry for my low response.

I replicated the situation in an empty scene with a bunch of cubes and an ES3ReferenceMgr.
This simple script

Code: Select all

public class TestSave : MonoBehaviour
{
    [SerializeField] private Transform[] cubes;

    void Awake()
    {
        ES3.Load("cubes", cubes);
    }

    void OnDestroy()
    {
        ES3.Save("cubes", cubes);
    }
}
was attached to an empty gameObject. I generated the ES3UserType_Transform class with the position and rotation enabled. At runtime, I moved the position of some of the cubes. When reloading the scene, the position had been reset. Here's the SaveFile.es3 :

Code: Select all

{
	"cubes" : {
		"__type" : "UnityEngine.Transform[],UnityEngine.CoreModule",
		"value" : [
			null,null,null,null,null,null,null
		]
	}
}
The cubes were being destroyed before the execution of the above OnDestroy(). With OnDisable(), the save was working fine. So this is the exact same problem. With the debug tool, I managed to check the ES3ReferenceMgr gameObject state at this exact moment, and it was also already destroyed.

Here's the error message :

Code: Select all

InvalidOperationException: An Easy Save 3 Manager is required to load references. To add one to your scene, exit playmode and go to Assets > Easy Save 3 > Add Manager to Scene
ES3Types.ES3UnityObjectType.WriteObject (System.Object obj, ES3Writer writer, ES3+ReferenceMode mode) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3UnityObjectType.cs:40)
ES3Writer.Write (System.Object value, ES3Types.ES3Type type, ES3+ReferenceMode memberReferenceMode) (at Assets/Plugins/Easy Save 3/Scripts/Writers/ES3Writer.cs:229)
ES3Writer.WriteProperty (System.String name, System.Object value, ES3Types.ES3Type type, ES3+ReferenceMode memberReferenceMode) (at Assets/Plugins/Easy Save 3/Scripts/Writers/ES3Writer.cs:296)
ES3Writer.Write (System.Type type, System.String key, System.Object value) (at Assets/Plugins/Easy Save 3/Scripts/Writers/ES3Writer.cs:142)
ES3Writer.Write[T] (System.String key, System.Object value) (at Assets/Plugins/Easy Save 3/Scripts/Writers/ES3Writer.cs:129)
ES3.Save[T] (System.String key, T value, ES3Settings settings) (at Assets/Plugins/Easy Save 3/Scripts/ES3.cs:102)
ES3.Save[T] (System.String key, T value) (at Assets/Plugins/Easy Save 3/Scripts/ES3.cs:63)
GameManager.OnDestroy () (at Assets/Scripts/GameManager.cs:168)
Thank you for your help!
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Reference manager destroyed before other objects when stopping execution

Post by Joel »

Hi there,

Please could you private message me the test project you created, and also let me know the version of Unity you're using. I still don't appear to be able to replicate this at my end with the scripts you sent.

If Destroy is indeed working differently to how it's previously been documented, you would need to ensure that the priority of the ES3ReferenceMgr script is higher than that of your other scripts in the Script Execution Order settings:

https://docs.unity3d.com/Manual/class-MonoManager.html

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
r4scar_capac
Posts: 4
Joined: Mon Mar 14, 2022 3:28 pm

Re: Reference manager destroyed before other objects when stopping execution

Post by r4scar_capac »

Will do! I tried to change the script execution order, but it doesn't seem to change the destruction order, the problem is the same.
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Reference manager destroyed before other objects when stopping execution

Post by Joel »

Hi there,

Thanks for sending that over, I've managed to replicate it from what you've sent (though it still seems very intermittent).

In this case it looks like Unity have changed the specification (either intentionally or unintentionally), so you would need to use a different event. For example, OnApplicationPause or OnApplicationQuit if you're trying to detect when the application closes. Or if you're using it to detect when the scene changes, you should instead put code before your SceneManager.LoadScene call which calls the save process before the scene is loaded.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
r4scar_capac
Posts: 4
Joined: Mon Mar 14, 2022 3:28 pm

Re: Reference manager destroyed before other objects when stopping execution

Post by r4scar_capac »

I put it before loading the scene and it worked well. Thanks for the help.
Post Reply