I'm loading a player save game at startup. This save includes a string entry that I'm trying to load into persistent data manager with its ApplySaveData method. Upon doing so I receive the following exception from Lua- "Cannot assign to a null value. Are you trying to assign to a nonexistent table element?."
When debugging I noticed that this can be avoided by delaying the load of save data by several frames by running it in a coroutine, but obviously this is not an ideal long-term solution.
Is this caused by an asynchronous load of the dialogue databases? If so, am I able to detect when this load is complete?
If not, are there any other suggestions that might help resolve this?
Please feel free to let me know if any additional information is needed.
Cheers,
-Jason
ApplySaveData Exception at Startup
Re: ApplySaveData Exception at Startup
Hi Jason,
Yes, there are callbacks. Can you share the code you're using to load your data and then call ApplySaveData?
Yes, there are callbacks. Can you share the code you're using to load your data and then call ApplySaveData?
- KrymsonVerse
- Posts: 6
- Joined: Sat Jul 25, 2020 3:49 am
Re: ApplySaveData Exception at Startup
Hi Tony,
Sure. Here's what I hope are the relevant bits.
PlayerProfile is a singleton pattern monobehavior and is called by some data-hungry systems at start-up as profileFlag contains entries for many of our player configurations and the load system is trying to feed all of our sub-systems (including Dialogue System) at the same time.
Sure. Here's what I hope are the relevant bits.
PlayerProfile is a singleton pattern monobehavior and is called by some data-hungry systems at start-up as profileFlag contains entries for many of our player configurations and the load system is trying to feed all of our sub-systems (including Dialogue System) at the same time.
Code: Select all
public class PlayerProfile: Monobehavior
Dictionary<string, object> profileFlag = new Dictionary<string, object>();
public void SavePlayerProfile()
{
profileFlag["PROFILE.DialogueData"] = PersistentDataManager.GetSaveData();
// ... the dictionary is serialized and saved to a binary file
}
public void LoadPlayerProfile()
{
PersistentDataManager.Reset();
// ... the dictionary is deserialized and loaded from a binary file
string dialogueData = (string)profileFlag[["PROFILE.DialogueData"];
if(!string.IsNullOrEmpty(dialogueData))
{
PersistentDataManager.ApplySaveData(dialogueData);
}
}
}
Re: ApplySaveData Exception at Startup
Hi,
To know when Dialogue System initialization is complete, you can hook into DialogueManager.instance.initializationComplete. Example:
Or you can check DialogueManager.instance.isInitialized.
To know when Dialogue System initialization is complete, you can hook into DialogueManager.instance.initializationComplete. Example:
Code: Select all
void Awake()
{
DialogueManager.instance.initializationComplete += OnInitializationComplete;
}
void OnInitializationComplete()
{
DialogueManager.instance.initializationComplete += OnInitializationComplete;
// (From this point on you can access/change Dialogue System stuff)
}
- KrymsonVerse
- Posts: 6
- Joined: Sat Jul 25, 2020 3:49 am
Re: ApplySaveData Exception at Startup
Thanks for the prompt response! Unfortunately it doesn't seem to delay the load long enough to prevent the exception.
Does DialogueManager.instance.isInitialized account for the initialization of additional databases loaded through the ExtraDatabases component triggered On Start?
Does DialogueManager.instance.isInitialized account for the initialization of additional databases loaded through the ExtraDatabases component triggered On Start?
Re: ApplySaveData Exception at Startup
Hi,
No, it doesn't, because Extra Databases can be configured to load databases at any point, such as when entering a new scene or when a new character arrives. If Extra Databases is set to OnStart and the One Per Frame checkbox is unticked, then you can wait for the end of Unity's Start frame instead of checking DialogueManager.instance.initializationComplete:
No, it doesn't, because Extra Databases can be configured to load databases at any point, such as when entering a new scene or when a new character arrives. If Extra Databases is set to OnStart and the One Per Frame checkbox is unticked, then you can wait for the end of Unity's Start frame instead of checking DialogueManager.instance.initializationComplete:
Code: Select all
IEnumerator Start()
{
yield return new WaitForEndOfFrame(); // At end of frame, Dialogue Manager and Extra Databases will be done.
// (your initialization code here)
}