Search code examples
c#unity-game-enginedata-serialization

Unity: How to store some data from the game and restore it on the next run


In my game I have a collectible which is in abundance and I want each individual collectible to not respawn if the player has already collected it and returns to the scene. For example, there might be a hundred or so of these collectibles in one scene and if the player collects one of them, leaves the scene and then returns, the one they have collect doesn't respawn but the rest do.

After some research I think I'm supposed to use data serialization to store which collectibles have been collected and which haven't but I'm unsure of how to go about doing this and the concept is quite new to me. Could someone explain to me what I'm supposed to do please?

Thanks


Solution

  • Use PlayerPrefs to store the current state of the player.

    These are the options:

    1. PlayerPrefs does not support boolean so you can use integer (0 as false and 1 as true) and assign one integer to each collectible. pros: easier to implement. cons: uses too much memory if number of stored objects are very high and require more workload for read/write.

    2. assign one integer to multiple collectibles and store them bitwise and convert back and forth. pros: less memory and faster read/write for large number of stored objects. cons: limits the number of each integer to the number of bits in int32. that is 32.

    3. assign a large string to all collectibles and convert back and forth. pros: you can store more states other than true/false also you can use any encryption to secure the data from hack. cons: nothing I can think of.

    option1:

    //store
    PlayerPrefs.SetKey("collectible"+i, isCollected?1:0);
    
    //fetch
    isCollected = PlayerPrefs.GetKey("collectible"+i, 0) == 1;
    

    bitwise:

    int bits = 0;//note that collectiblesGroup1Count cannot be greater than 32
    for(int i=0; i<collectiblesGroup1Count; i++) 
        if(collectibleGroup1[i].isCollected)
           bits |= (1 << i);
    
    //store
    PlayerPrefs.SetKey("collectiblesGroup1", bits);
    
    //fetch
    bits = PlayerPrefs.GetKey("collectiblesGroup1", 0);//default value is 0
    for(int i=0; i<collectiblesGroup1Count; i++) 
        collectibleGroup1[i].isCollected = (bits && (1 << i)) != 0;
    

    string approach:

    string bits = "";//consists of many C's and N's each for one collectible
    for(int i=0; i<collectiblesCount; i++) 
        bits += collectibleGroup1[i].isCollected ? "C" : "N";
    
    //store
    PlayerPrefs.SetKey("collectibles", bits);
    
    //fetch
    bits = PlayerPrefs.GetKey("collectibles", "");
    for(int i=0; i<collectiblesCount; i++) 
        if(i < bits.Length)
            collectible[i].isCollected = bits[i] == "C";
        else
            collectible[i].isCollected = false;