Search Unity

Using data persistence/serialization to save item count and stop items from reappearing

Discussion in 'Scripting' started by KBurchfiel, Jun 25, 2016.

  1. KBurchfiel

    KBurchfiel

    Joined:
    May 16, 2016
    Posts:
    7
    Hi everyone--I was having a horrible time trying to figure out (1 how to save my player's pickup count, and (2 how to stop collected pickups from reappearing, so the player couldn't boost the score by reloading the game and re-collecting the same pickups. I wanted to retain my score and item statuses even after quitting and reloading a game file. (My goal was a setup similar to Banjo-Tooie, where the notes don't reappear once you've collected them, unlike in Banjo-Kazooie.)

    Thanks to some help by"Flaring Afro and Iamrahulmaurya in the answers section, I was directed to the brilliant Mike Geig tutorial on data persistence and serialization. With a couple modifications to his script, I'm now able to save my pickup score, and prevent items from reappearing.

    I'll post all 3 scripts that I'm using here in 3 separate posts. This may be common sense to many of you, but this was the sort of script I was searching all over for as a newcomer to Unity, so I thought it would be useful to put here.

    Definitely watch the Mike Geig tutorial too, though.

    Script 1: Script for increasing item pickup count and preventing collected from reappearing

    This script adds to your pickup count when you go over an item, and also sets the item's unique "Pickupstate" to 0. I then use an update function to destroy any items with a Pickupstate to 0, and the item won't come back after you save. This works because the item states and pickup counts are 'stored' in the Game Control script.
    I originally set their 'active' status to 'false' as well, but I realized this was redundant so I removed it from the code. This script supports just 1 pickup, but I successfully increased it to 80 pickups for my game. (Although it grew to more than 1,000 lines! Lots of copying and pasting.)

    Code (csharp):
    1.  
    2. using UnityEngine;
    3.  
    4. using System.Collections;
    5.  
    6.  
    7.  
    8.  
    9.  
    10. public class Objectpickuppersistence: MonoBehaviour {
    11.  
    12.  
    13.  
    14.  
    15.  
    16.   public GameObject Pickup1;
    17.  
    18.  
    19.  
    20.  
    21.  
    22.   void OnTriggerEnter(Collider other)
    23.  
    24.   {
    25.  
    26.  
    27.  
    28.   if (other.gameObject.CompareTag ("Pickup1"))
    29.  
    30.   {
    31.  
    32.   GameControl.control.Pickup1count +=1;
    33.  
    34.   GameControl.control.Pickup1state = 0;
    35.  
    36.  
    37.  
    38.   }
    39.  
    40.  
    41.  
    42.   }
    43.  
    44.  
    45.  
    46.   void Update()
    47.  
    48.   {
    49.  
    50.   if (GameControl.control.Pickup1state == 0)
    51.  
    52.   {
    53.  
    54.   Destroy (Pickup1);
    55.  
    56.   }
    57.  
    58.  
    59.  
    60. }
    61.  
    62. }
    63.  
     
    Last edited: Jun 26, 2016
  2. KBurchfiel

    KBurchfiel

    Joined:
    May 16, 2016
    Posts:
    7
    Script 2: this is Mike Geig's Game Control script--I just inserted my variables in place of his "health" and "experience" variables. I have it attached to an empty Game Control object in my hierarchy.
    I also changed the variables under the [Serializable] class from Public Float to Public Int, since Monodevelop was giving me an error message about converting from a float to an integer.
    To make sure this works, I set the initial item state for each item to "1," so that it's changed to 0 when the character collides with the item.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3.  
    4. using System.Collections;
    5.  
    6. using System;
    7.  
    8. using System.Runtime.Serialization.Formatters.Binary;
    9.  
    10. using System.IO;
    11.  
    12.  
    13.  
    14. public class GameControl: MonoBehaviour {
    15.  
    16.  
    17.  
    18.   public int Pickupcount;
    19.  
    20.   public int Pickup1state;
    21.  
    22.   public int Pickup2state;
    23.  
    24.   public static GameControl control;
    25.  
    26.  
    27.  
    28.  
    29.  
    30.   void Awake () {
    31.  
    32.   if (control == null) {
    33.  
    34.   DontDestroyOnLoad (gameObject);
    35.  
    36.   control = this;
    37.  
    38.   } else if (control != this) {
    39.  
    40.   Destroy (gameObject);
    41.  
    42.   }
    43.  
    44.  
    45.  
    46.   }
    47.  
    48.  
    49.  
    50.   void OnGUI()
    51.  
    52.   { GUI.Label(new Rect(20, 20, 200, 30), "Level code count: " + Pickupcount);
    53.  
    54.   }
    55.  
    56.  
    57.  
    58.  
    59.  
    60.  
    61.  
    62. public void Save()
    63.  
    64. {
    65.  
    66.   BinaryFormatter bf = new BinaryFormatter ();
    67.  
    68.   FileStream file = File.Create(Application.persistentDataPath + "/playerInfo.dat");
    69.  
    70.  
    71.  
    72.   PlayerData data = new PlayerData ();
    73.  
    74.  
    75.  
    76.   data.Pickupcount = Pickupcount;
    77.  
    78.   data.Pickup1state = Pickup1state;
    79.  
    80.   data.Pickup2state = Pickup2state;
    81.  
    82.  
    83.  
    84.   bf.Serialize (file, data);
    85.  
    86.   file.Close ();
    87.  
    88. }
    89.  
    90.  
    91.  
    92.   public void Load()
    93.  
    94.   {
    95.  
    96.   if (File.Exists (Application.persistentDataPath + "/playerInfo.dat")) {
    97.  
    98.   BinaryFormatter bf = new BinaryFormatter ();
    99.  
    100.   FileStream file = File.Open(Application.persistentDataPath + "/playerInfo.dat", FileMode.Open);
    101.  
    102.   PlayerData data = (PlayerData) bf.Deserialize (file);
    103.  
    104.   file.Close ();
    105.  
    106.  
    107.  
    108.   Pickupcount = data.Pickupcount;
    109.  
    110.   Pickup1state = data.Pickup1state;
    111.  
    112.   Pickup2state = data.Pickup2state;
    113.  
    114.   }
    115.  
    116.   }
    117.  
    118.  
    119.  
    120. }
    121.  
    122.  
    123.  
    124. [Serializable]
    125.  
    126. class PlayerData
    127.  
    128. {
    129.  
    130.   public int Pickupcount;
    131.  
    132.   public int Pickup1state;
    133.  
    134.   public int Pickup2state;
    135.  
    136.   }
    137.  
     
    Last edited: Jun 25, 2016
  3. KBurchfiel

    KBurchfiel

    Joined:
    May 16, 2016
    Posts:
    7
    Script 3: Load and save buttons, also from Mike Geig's script. Applied to the character's camera:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3.  
    4. using System.Collections;
    5.  
    6.  
    7.  
    8. public class Adjustscript : MonoBehaviour {
    9.  
    10.  
    11.  
    12.   void OnGUI()
    13.  
    14.  
    15.  
    16.   {
    17.  
    18.   if (GUI.Button(new Rect(10, 100, 100, 30), "Levelcodes up"))
    19.  
    20.   {
    21.  
    22.   GameControl.control.Pickup1count += 10;
    23.  
    24.   }
    25.  
    26.   if (GUI.Button(new Rect(10, 140, 100, 30), "Levelcodes down"))
    27.  
    28.   {
    29.  
    30.   GameControl.control.Pickup1count -=10;
    31.  
    32.   }
    33.  
    34.  
    35.  
    36.   if (GUI.Button(new Rect(10, 180, 100, 30), "Save"))
    37.  
    38.   {
    39.  
    40.   GameControl.control.Save();
    41.  
    42.   }
    43.  
    44.   if (GUI.Button(new Rect(10, 220, 100, 30), "Load"))
    45.  
    46.   {
    47.  
    48.   GameControl.control.Load();
    49.  
    50.   }
    51.  
    52.   }
    53.  
    54.  
    55.  
    56. }
    57.  
     
    Last edited: Jun 25, 2016