Page 1 of 1
CharacterInfo Cache - Memory Question
Posted: Wed Jan 26, 2022 11:04 pm
by VoodooDetective
We're using Addressables to load basically everything in our game. Lately, I've been trying to track down an issue where our character portraits (and their animations) never seem to leave memory once they've been loaded.
I'm not 100% sure, but it seems like maybe something called m_characterInfoCache in ConversationModel could be keeping portraits around indefinitely? I guess my question is:
- Does m_characterInfoCache persist between conversations / scenes?
- Is there anywhere else that character portraits get cached?
Re: CharacterInfo Cache - Memory Question
Posted: Thu Jan 27, 2022 8:37 am
by Tony Li
Hi,
When Unity loads an asset into memory, and that asset references another asset, Unity will load the referenced asset, too.
So if the dialogue database's actors reference portrait images, Unity will load the portrait images when it loads the dialogue database.
If this is an issue, another option is to use the
SetPortrait() sequencer command with Addressables.
Re: CharacterInfo Cache - Memory Question
Posted: Thu Jan 27, 2022 2:12 pm
by VoodooDetective
Ah, so I'm actually storing the portraits on the DialogueActor objects on a scene-by-scene basis.
THAT SAID, I did more digging this morning and tracked the issue down to two variables in the dialogue system that aren't being clearing between conversations:
The first is in DialogueSystemController:
Code: Select all
public void OnEndConversation(ConversationController endingConversationController)
{
activeConversation = null; <------ THIS WAS MISSING
// Find and remove the record associated with the ConversationController:
var record = m_activeConversations.Find(r => r.conversationController == endingConversationController);
if (record != null)
{
m_activeConversations.Remove(record);
// Promote a remaining active conversation, or clear out the active conversation properties:
if (m_activeConversations.Count > 0)
{
var nextRecord = m_activeConversations[0];
m_conversationController = nextRecord.conversationController;
currentActor = nextRecord.actor;
currentConversant = nextRecord.conversant;
}
else
{
m_conversationController = null;
currentActor = null;
currentConversant = null;
}
// Restore UI:
m_originalDialogueUI = record.originalDialogueUI;
m_originalDisplaySettings = record.originalDisplaySettings;
m_isOverrideUIPrefab = record.isOverrideUIPrefab;
RestoreOriginalUI();
}
// End of conversation checks:
m_luaWatchers.NotifyObservers(LuaWatchFrequency.EndOfConversation);
CheckAlerts();
}
The second in is StandardUISubtitlePanel:
Code: Select all
protected virtual void OnHidden()
{
panelState = PanelState.Closed;
if (deactivateOnHidden) gameObject.SetActive(false);
currentSubtitle = null; <------ THIS WAS MISSING
onClosed.Invoke();
}
When those aren't set to null, the portrait and its animations stick around between scenes.
Re: CharacterInfo Cache - Memory Question
Posted: Thu Jan 27, 2022 2:17 pm
by Tony Li
You can count on those being added in version 2.2.25.
Re: CharacterInfo Cache - Memory Question
Posted: Thu Jan 27, 2022 2:44 pm
by VoodooDetective
Awesome! Thanks very much!
Re: CharacterInfo Cache - Memory Question
Posted: Thu Jan 27, 2022 4:47 pm
by mathygreen
We're using Addressables to load basically everything in our game. Lately, I've been trying to track down an issue where our character portraits and their animations never seem to leave memory once they've been loaded.
I'm not 100% sure, but it seems like maybe something called m characterInfoCache in ConversationModel could be keeping portraits around indefinitely Does m characterInfoCache persist between conversations scenes.
Re: CharacterInfo Cache - Memory Question
Posted: Thu Jan 27, 2022 5:06 pm
by Tony Li
Hi,
Currently it can. If you make the two changes VoodooDetective posted above, then it shouldn't persist. (I haven't confirmed that yet, but I'll try to post a patch with those changes here later today.)
DS_CharacterInfoPatch_2022-01-27.unitypackage
Re: CharacterInfo Cache - Memory Question
Posted: Thu Jan 27, 2022 8:47 pm
by Tony Li
Addressables are an additional consideration. You'll want to unload them yourself when you're certain you won't need them again.
The SetPortrait() sequencer command can load portraits from Addressables. Since a portrait could be used for multiple separate barks in sequence or multiple conversations one right after the other, we don't want to cause a performance issue by unloading an Addressable portrait only to have to load it again shortly after. When you know you're done with the portrait, just call DialogueManager.UnloadAsset() on it.