Unique identifiers for MonoBehaviours of the same GameObject

Hello all. I’m working on save/load system for my game and faced with a problem appearing in a trivial scenario when the data of multiple MonoBehaviour scripts of the same type and attached to the same GameObject should be saved/restored. How can I identify these MonoBehaviours in order to assign restored data to the same MonoBehaviours that were saved? On GameObjects level I can use sibling indexes but there seems no access to MonoBehaviour indexes of the internal array of the GameObject. Some workaround would be using indexes of the array returned by GameObject.GetComponents() method but it seems not reliable as I’m not sure that the order of MonoBehaviours in this array will be kept between game sessions and on different PCs.

class DataHolderScript : MonoBehaviour
{
    public int DataValue;
}

GameObject gameObject;

void Save()
{
    gameObject = new GameObject();

    DataHolderScript dataFirst = gameObject.AddComponent<DataHolderScript>();
    dataFirst.DataValue = 1;
    DataHolderScript dataSecond = gameObject.AddComponent<DataHolderScript>();
    dataSecond.DataValue = 2;

    Serialize(new int[] { dataFirst.DataValue, dataSecond.DataValue });
}

void Load()
{
    int[] dataValues = Deserialize();

    DataHolderScript[] dataHolders = gameObject.GetComponents<DataHolderScript>();

    //Can I assume that the order of DataHolderScripts persists between game sessions (probably on different PCs)???
    dataHolders[0].DataValue = dataValues[0];
    dataHolders[1].DataValue = dataValues[1];
}

Thanks in advance.

You just need to impose your own unique identifier:

public class DataHolder : Monobehaviour
{
    public string GUID = System.Guid.NewGuid().ToString();
}

This also means you need to save out the unique identifier. Meaning you should make a serialisable surrogate for the classes you intend to save out.

Also you realise that your Save() function is just going to return the same component twice?

1 Like

The order of components should be guarenteed as some Unity features (like audio filters) actually rely on it.

1 Like

Yes, something like this is the worst case scenario. But I’m hoping to use more generic and universal approach since I have many classes in different hierarchies.

As for the Save() function, I don’t fully understand what is wrong with it, but it does not matter, as it just an illustrative code example.

Yes, that is the answer. Thank you for the link.