Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Saving level/scene details to a file

Discussion in 'Scripting' started by SuperNoctiz, Jan 28, 2015.

  1. SuperNoctiz

    SuperNoctiz

    Joined:
    Jan 24, 2014
    Posts:
    20
    Hello there, hope this is the right place to ask or debate this.

    I've been developing this game for android with the idea of creating at least 30 levels, each level with X amount of coins to collect.

    Today I watched the live training in Persistence, Saving and Loading which helped me a lot, but what I want now is to save the current state of a level, for example, a player picks up 2 out of 5 coins in this level and continues to the next one (saving the current level). Then the next time the player comes back to that level, those 2 coins continue inactive and the rest still there to pick up.

    I've done this so far:
    Code (CSharp):
    1. public void Save () {
    2.         BinaryFormatter bf = new BinaryFormatter ();
    3.         FileStream file = File.Create (Application.persistentDataPath + "/playerInfo.dat");
    4.  
    5.         PlayerData data = new PlayerData ();
    6.         data.totalCoins = totalCoins;
    7.  
    8.         bf.Serialize (file, data);
    9.         file.Close ();
    10.  
    11.         Debug.Log ("Saved!");
    12.     }
    13.  
    14.     public void Load () {
    15.         if (File.Exists (Application.persistentDataPath + "/playerInfo.dat")) {
    16.             BinaryFormatter bf = new BinaryFormatter ();
    17.             FileStream file = File.Open (Application.persistentDataPath + "/playerInfo.dat", FileMode.Open);
    18.  
    19.             PlayerData data = (PlayerData)bf.Deserialize(file);
    20.             file.Close();
    21.  
    22.             totalCoins = data.totalCoins;
    23.  
    24.             Debug.Log ("Loaded!");
    25.         }
    26.     }
    27. }
    28.  
    29. [Serializable]
    30. public class Level {
    31.  
    32.     public string name;
    33.     public int levelIndex;
    34.     public string achievementID;
    35.     public int coinsInLevel;
    36.     public GameObject[] coins;
    37. }
    38.  
    39. [Serializable]
    40. class PlayerData {
    41.     public int totalCoins;
    42.     public Level level;
    43. }
    So basically I have GameObject[] coins to control if the coin has been picked up or not (with coins[].activeSelf) and all that stuff.

    The problem is, I can't save a class into a file nor can I save the array.

    What should I do?
     
  2. ZO5KmUG6R

    ZO5KmUG6R

    Joined:
    Jul 15, 2010
    Posts:
    490
    You could try using a BinaryWriter/BinaryReader

    Code (CSharp):
    1. using System.IO;
    2.  
    3. int numCollectedCoins = 0;
    4.  
    5. void Save(){
    6.    using(var w = new BinaryWriter(File.OpenWrite("sav.dat"))){
    7.       w.Write(Convert.ToInt32(5)) //5 coins collected [example]
    8.    }
    9. }
    10.  
    11. void Load(){
    12.    using(var r = new BinaryWriter(File.OpenRead("sav.dat"))){
    13.       numCollectedCoins = r.ReadInt32();
    14.    }
    15. }
    16.  
    17.  
     
  3. SuperNoctiz

    SuperNoctiz

    Joined:
    Jan 24, 2014
    Posts:
    20
    Thanks for the quick reply!
    That would work to know the amount of coins the player collected which is what I already have, maybe I didn't give enough details.
    What I specifically want is to know which coins the player already collected in that level.

    Sorry for the paint-ish image, but I think it's easier to explain like this, since english is not my native language..
    So the player in this pic caught the coin behind him and for whatever reason missed the one above lava but passed the level eitherway.
    Now the player wants to go back to that level to pick up the coin he missed, not having to pick up the other he already caught.

    Sorry to bother you guys
     
  4. ZO5KmUG6R

    ZO5KmUG6R

    Joined:
    Jul 15, 2010
    Posts:
    490
    Something like this should work

    Code (CSharp):
    1. using System;
    2. using System.IO;
    3. GameObject[] coins;
    4.  
    5. void Save(){
    6.     coins =  GameObject.FindGameObjectsWithTag("Coin")
    7.    using(var w = new BinaryWriter(File.OpenWrite("sav.dat"))){
    8.       w.Write(Convert.ToInt16(coins.Length)); //Int16 supports up to 32767
    9.       foreach(GameObject g in coins){
    10.         w.Write(g.active); // Writes byte 0 or 1
    11.       }
    12.    }
    13. }
    14. void Load(){
    15.     coins =  GameObject.FindGameObjectsWithTag("Coin")
    16.    using(var r = new BinaryWriter(File.OpenRead("sav.dat"))){
    17.         int numCoins = r.ReadInt16();
    18.         for(int i = 0; i < numCoins; i++){
    19.             coins[i].SetActive(r.ReadBoolean());
    20.         }
    21.    }
    22. }
     
    SuperNoctiz likes this.
  5. SuperNoctiz

    SuperNoctiz

    Joined:
    Jan 24, 2014
    Posts:
    20
    Amazing! That should work, going to give it a try and I'll give some feedback later :)
    Much thanks


    update: it worked! Thank you!
     
    Last edited: Jan 28, 2015