Hello, I have a dialogue manager that retrieves sentences from a scriptable object. I then store the list of sentences from this scriptable object into a local list. And to iterate through the dialogue correctly, I remove the sentences that have been iterated through (there are reasons why I’m doing it this way).
The problem that I’m having, is that the scriptable object its data get removed while I’m only removing the data from the local list. Does anyone know how to fix this, and why this happens? I oversimplified the code down below, but that’s basically what it gets down to.
public class DialogueInfo : ScriptableObject
{
[SerializeField]
private List<SentenceInfo> _sentences = new List<SentenceInfo>();
public List<SentenceInfo> GetSentences { get { return _sentences; } }
}
public class DialogueManager : MonoBehaviour
{
[SerializeField]
private DialogueInfo _dialogueInfo;
private List<SentenceInfo> _remainingSentences;
SetRemainingSentences()
{
_remainingSentences = _dialogueInfo.GetSentences;
}
RemoveFromList()
{
_remainingSentences.RemoveAt(0);
}
}
You don’t have a “local list”. All you have is a local variable that hold a reference to the exact same List instance stored in your ScriptableObject. You should learn the basic differences between value types and reference types. This line:
_remainingSentences = _dialogueInfo.GetSentences;
does not copy or duplicate the list that is returned by GetSentences. You just store the same reference in your local variable. Since your List actually contains more reference types, just duplicating the List might not be enough since both lists would still contain the same “SentenceInfo” instances. So while you can savely remove elements from your duplicated list in this case, changes to a SentenceInfo instance would still also be applied to the SentenceInfo in your ScriptableObject.
The easiest way to decouple the whole scriptableobject is to just use Instantiate and clone the whole ScriptableObject so you get a copy in memory.
Also note that you should work on your naming of properties and methods. “GetSentences” would imply a method and not a property. You should name it just “Sentences”.
To fix your actual issue you could just do:
void SetRemainingSentences()
{
_remainingSentences = new List<SentenceInfo>(_dialogueInfo.GetSentences);
}
This will create a new seperate List instance and you will copy all elements from the list in your scriptable object into the new list.