Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Unique identifiers for MonoBehaviours of the same GameObject

Discussion in 'Scripting' started by Efril, Aug 20, 2022.

  1. Efril

    Efril

    Joined:
    Aug 31, 2013
    Posts:
    79
    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.

    Code (CSharp):
    1.  
    2. class DataHolderScript : MonoBehaviour
    3. {
    4.     public int DataValue;
    5. }
    6.  
    7. GameObject gameObject;
    8.  
    9. void Save()
    10. {
    11.     gameObject = new GameObject();
    12.  
    13.     DataHolderScript dataFirst = gameObject.AddComponent<DataHolderScript>();
    14.     dataFirst.DataValue = 1;
    15.     DataHolderScript dataSecond = gameObject.AddComponent<DataHolderScript>();
    16.     dataSecond.DataValue = 2;
    17.  
    18.     Serialize(new int[] { dataFirst.DataValue, dataSecond.DataValue });
    19. }
    20.  
    21. void Load()
    22. {
    23.     int[] dataValues = Deserialize();
    24.  
    25.     DataHolderScript[] dataHolders = gameObject.GetComponents<DataHolderScript>();
    26.  
    27.     //Can I assume that the order of DataHolderScripts persists between game sessions (probably on different PCs)???
    28.     dataHolders[0].DataValue = dataValues[0];
    29.     dataHolders[1].DataValue = dataValues[1];
    30. }
    31.  
    Thanks in advance.
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,883
    You just need to impose your own unique identifier:

    Code (CSharp):
    1. public class DataHolder : Monobehaviour
    2. {
    3.     public string GUID = System.Guid.NewGuid().ToString();
    4. }
    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?
     
    Efril likes this.
  3. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,528
    Efril likes this.
  4. Efril

    Efril

    Joined:
    Aug 31, 2013
    Posts:
    79
    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.
     
  5. Efril

    Efril

    Joined:
    Aug 31, 2013
    Posts:
    79