Saving and loading the local high score

In this section, we will be creating two scripts for saving and loading the high score from our local machine. The first script will be the UsersData script, which will contain all the functions to save and load the score to our local machine by using the PlayerPrefs class. Then, we will create the LocalHiScore script, which will contain the function to sort user scores and check for the final score submission. Finally, we will go back to the HiScore script to create a LocalHiscore object to save and load high scores locally.

Prepare for Lift Off

Before we start, we need to know the basic parameters we need to include in the high-score table. We will need the order number, username, and the user score, as shown in the following screenshot:

Prepare for Lift Off

Engage Thrusters

We will start by creating the UsersData class to contain the user data and functions, which will load and save the user data to the local machine using PlayerPref:

  1. In Unity, go to Assets | Create | Javascript, name it UsersData and double-click to open MonoDevelop, and then replace the script as follows (you should remove all the existing script that is automatically created with Unity):
    class UsersData {
      //Game Key - to make sure that each object has different key set
      public var keylocal : String = "ShooterLocal";
      private var s_keyScore : String = "Score";
      private var s_keyName : String = "Name";
      
      private var s_name : String;
      private var int_score : int;
      private var as_randomNames : String[] = ["Antony", "John", "Will", "Kate", "Jill"]; //To get a random name
      
      //Setting the user name and score
      public function Init(name : String, score : int) : void {
        int_score = score;
        s_name = name;
      }
      
      public function GetName() : String {
        return s_name;
      }
      
      public function GetScore() : int {
        return int_score;
      }
  2. We just created the Init() function to set up the score and name from this object. Next, we will create the SaveLocal() function, which will get the index and save the name and score to our local machine by using PlayerPref:
    //Saving Data
      public function SaveLocal (index : int) : void {
        //Saving user score
        PlayerPrefs.SetInt(keylocal + s_keyScore + index.ToString(), int_score);
        //Saving user name
        PlayerPrefs.SetString(keylocal + s_keyName + index.ToString(), s_name);
      }
  3. Then, we will create the LoadLocal(), LoadScore(), and LoadName() functions, which will load the user's score and name from the index:
      //Loading Data
      public function LoadLocal (index : int) : void {
        int_score = LoadScore(index);
        s_name = LoadName(index);
      }
      
      private function LoadScore (index : int) : int {
        //Checking to see if the value already exists
        var s_newKey : String = keylocal + s_keyScore + index.ToString();
        if (PlayerPrefs.HasKey(s_newKey)) {
          return PlayerPrefs.GetInt(keylocal + s_keyScore + index.ToString());
        } else {
          //If no key exist return 0 score
          return 0;
        }
      }
      
      private function LoadName (index : int) : String {
        //Checking to see if the value already exist
        var s_newKey : String = keylocal + s_keyName + index.ToString();
        if (PlayerPrefs.HasKey(s_newKey)) {
          return PlayerPrefs.GetString(keylocal + s_keyName + index.ToString());
        } else {
          //If no key exist return random name;
          var int_random : int = Random.Range(0, as_randomNames.length);
          return as_randomNames[int_random];
        }
      }
    }
  4. Next, we will continue creating the next script, so let's create the LocalHiScore script and replace it as follows:
    class LocalHiScore {
      private var int_maxUser : int;
      private var int_minScore : int;
      private var as_users : UsersData[]; //To get all loader data name
    
    }
  5. Here, we set up the LocalHiScore script to have class keyword, which is similar to the UsersData script, because we don't need this class to inherit from MonoBehaviour. We also set up all necessary parameters for this class. Next, we will add the setup function and load function to this class. Let's add the following highlighted code:
    class LocalHiScore {
      private var int_maxUser : int;
      private var int_minScore : int;
      private var as_users : UsersData[]; //To get all loader data name
    
      //Setting the maximum user to display on the menu 
      //Loading the user data and store it in here
      public function SetMaxUser (maxUser : int ) : void 
        int_maxUser = maxUser;
        //Loading all the users data from the local machine
        LoadGameLocal();
      }
    
      public function LoadGameLocal () : void {
        //Creating the array of UsersData object
        as_users = new UsersData[int_maxUser];
        //Creating the array of int to store all the user scores data
        var a_scores : int[] = new int[int_maxUser];
        for (var i: int = 0; i < int_maxUser; i++) {
          //Creating the user data object, load data, and store it to the UsersData array
          var obj_user : UsersData = new UsersData();
          obj_user.LoadLocal(i);
          as_users[i] = obj_user;
          a_scores[i] = as_users[i].GetScore();
        }
        //Getting the minimum score for the save data purpose
        int_minScore = Mathf.Min(a_scores);
      }
    }
  6. Then, we will add the SaveGame (scores : int, name : String) and SortUser (array : UsersData[]) functions to sort the user data and save it to the local machine after the LoadGameLocal() function, as shown highlighted in the following code:
     class LocalHiScore {
      //Above Script
      //////////////////////////
    
      public function LoadGameLocal () : void {
        //Creating the array of UsersData object
        as_users = new UsersData[int_maxUser];
        //Creating the array of int to store all the user scores data
        var a_scores : int[] = new int[int_maxUser];
        for (var i: int = 0; i < int_maxUser; i++) {
          //Creating the user data object, load data, and store it to the UsersData array
          var obj_user : UsersData = new UsersData();
          obj_user.LoadLocal(i);
          as_users[i] = obj_user;
          a_scores[i] = as_users[i].GetScore();
        }
        //Getting the minimum score for the save data purpose
        int_minScore = Mathf.Min(a_scores);
      }
    
      public function SaveGame (scores : int, name : String) : void {
        //Submitting the score if the score is higher than the minimum score of the database
        if (scores >= int_minScore) {
          var a_newData : Array = new Array(as_users);
          //Removing the last Array
          a_newData.Pop();
          //Create new user and save it to array
          var obj_user : UsersData = new UsersData();
          obj_user.Init(name, scores);
          a_newData.Add(obj_user);
          //Setting JS Array back to Builtin
          as_users = a_newData.ToBuiltin(UsersData);
          //Sorting Data
          SortUser(as_users);
        }
        for (var i: int = 0; i < int_maxUser; i++) {
          as_users[i].SaveLocal(i);
        }
      }
    
      //Sorting the score from the maximum to minimum
      private function SortUser (array : UsersData[]) : void {
        for (var i : int = 0; i < array.length-1; i++) {
          for (var j : int = i+1; j < array.length; j++) {
            //If the first score is lower than second score swap the position
            if (array[i].GetScore() <= array[j].GetScore()) {
              var obj_temp : UsersData = array[i];
              array[i] = array[j];
              array[j] = obj_temp;
            }
          }
        }
      }
    }
  7. We will add two more functions for getting the user score and name from the index to use it to display on the menu after the SortUser (array : UsersData[]) function, as shown in the following code:
    class LocalHiScore {
      //Above Script
      //////////////////////////
      
      //Sort the score from the maximum to minimum
      private function SortUser (array : UsersData[]) : void {
        for (var i : int = 0; i < array.length-1; i++) {
          for (var j : int = i+1; j < array.length; j++) {
            //If the first score is lower than the second score swap the position
            if (_array[i].GetScore() <= array[j].GetScore()) {
              var obj_temp : UsersData = array[i];
              array[i] = array[j];
              array[j] = obj_temp;
            }
          }
        }
      }
      
      public function GetNameData(index : int) : String {
        return as_users[index].GetName();
      }
    
      public function GetScoreData(index : int) : int {
        return as_users[index].GetScore();
      }
    } 
  8. We are almost done. Finally, we will go back to the HiScore script to add some scripts and enable the game to save and load the high score locally. Let's go back to the HiScore script, at the line before the Start() function, and add the following highlighted code:
    private var b_isClickSubmit : boolean = false; //Checking if the submit button is clicked by the user
    
    private var obj_localHiScore : LocalHiScore; //Creating the LocalHiScore Object
    
    public function Start() : void {
      //Initializing
  9. Then, we will go to the Start() function and create the LocalHiScore object, as shown highlighted in the following code:
    public function Start() : void {
      //Initializing
      e_page = Page.GAMEOVER;
      scrollPosition = Vector2.zero;
      b_isClickRestart = false;
      b_isClickSubmit = false;
      //Creating a Local Hiscore Object
      obj_localHiScore = new LocalHiScore();
      //Setting the maximum scores to show on the table & loading the local high score data here
      obj_localHiScore.SetMaxUser(maxUsers);
    }

    In this Start() function, we created the new LocalHiScore object, and set the max user display and load the user data from the local machine.

  10. We already have the user data object, and now we need to save the score by going to the GameoverPage() function inside the Submit button function and type the following highlighted code:
       //Submit button
        if (GUI.Button(new Rect((Screen.width - 240)*0.5, (Screen.height*0.1) + 200, 240, 30), "SUBMIT")) {
          b_isClickSubmit = true;
          //TODO: Submitting both local and server high score here
       obj_localHiScore.SaveGame(TimeScoreUI.int_currentScore, userName); //Submitting to the local score
        } 
  11. This is the code for saving the score locally after the player clicks on the SUBMIT button. Then, we save the score to our local machine. Now we need to load the user score data and display it on the menu in the scrolled area by going to the LocalScorePage() function and adding the highlighted code as follows:
    //Loading the local scores
    private function LocalScorePage() : void {
      //Creating the background box
      GUI.Box(new Rect(Screen.width*0.1, Screen.height*0.1, Screen.width * 0.8, Screen.height * 0.8), "LOCAL HI-SCORES", GUI.skin.GetStyle("Box2"));
      //Creating the scrolled area and scrollbar to view the player scores
      scrollPosition = GUI.BeginScrollView (new Rect ((Screen.width - 320)*0.5, (Screen.height*0.1) + 80, 320, 180), scrollPosition, new Rect (0, 0, 300, 30*maxUsers));
      for (var i: int = 0; i < maxUsers; i++) {
        //Set the number of the user
        GUI.Label(new Rect(0, i * 30, 35, 30), (i+1).ToString() + ".");
        //TODO: Showing the user name and score here
        GUI.Label(new Rect(35, i * 30, 120, 30), obj_localHiScore.GetNameData(i));
          GUI.Label(new Rect(155, i * 30, 145, 30), GlobalFunction.addCommasInt(obj_localHiScore.GetScoreData(i)), GUI.skin.GetStyle("Score"));
        }
      GUI.EndScrollView (); //End Scroll Area
      if (GUI.Button(new Rect((Screen.width - 240)*0.5, (Screen.height*0.1) + 280, 240, 30), "BACK")) {
        e_page = Page.GAMEOVER;
      }
    }

These two lines will load the username and score, and display it on the scrolled area in the LOCAL HI_SCORE menu page.

Next, we can go back to Unity, click Play, and try to complete the game by killing all the enemies to bring up the GAMEOVER menu. Right now, we will be able to enter our name, submit the score, and see the high score board if we click on the LOCAL HI-SCORE button:

Engage Thrusters

We typed our name and clicked to submit the score.

Engage Thrusters

If we clicked on the LOCAL HI-SCORE button, we will see that our name and score appears on the scoreboard, as shown in the following screenshot:

Engage Thrusters

Objective Complete - Mini Debriefing

We just created two classes, UsersData and LocalHiScore, for saving and loading the user's local high score data and displayed it on the LOCAL HI-SCORE page by using the PlayerPrefs to save and load the array of UsersData objects. We also checked for the user submission score and sorted the score before saving it to the local object.

In the UsersData script, we started by creating the class UsersData {. This is because this class only contains the data and doesn't want to use any Start() or Update() function that inherits from the MonoBehaviour class. If we don't put the class keyword, Unity will automatically inherit this class from MonoBehaviour, which is the default setting for Unity Javascript, so it means that we can run this script without adding the class keyword.

Note

We can also inherit the class from MonoBehaviour in Javascript by using the class keyword, as shown in the following script:

class MyClass extends MonoBehaviour { }

The preceding script will also inherit MyClass from MonoBehaviour.

However, it will be too expensive to use. To make it easy to understand, all scripts that inherit from MonoBehaviour will have the Start(), Update() classes, and all the MonoBehaviour functions run in the Unity background.

The classes that aren't derived from MonoBehaviour objects, Start(), Update(), and so on, won't be called on MonoBehaviour unless they are connected to the game objects.

Next, we set up the necessary parameters for this class. Then, we save the score in the SaveLocal(index : int) function, which will take the index number of each user included with the local key and put in the PlayerPrefs key. This will allow us to save multiple users without having any problems.

In the SaveLocal() function, we use PlayerPrefs.SetInt(KeyString, int_score); to save the score and PlayerPrefs.SetString(KeyString, s_name); to save the username.

Next, we have the LoadLocal(index : int) function, which will take the index number of the users and load the username and score from the PlayerPrefs.

The LoadLocal() function will contain two functions. The first is LoadScore(index : int), which will load the user's score by using PlayerPrefs.HasKey(KeyString) to check for the similar key saved on this local machine. If it has, we will load the score by using the PlayerPrefs.GetInt(KeyString) function, and if not, we will return 0 for the score. The next function is LoadName(index : int), which is very similar to the LoadScore(index : int) function, but this time we will use PlayerPrefs.GetString(KeyString) to get the username. Also, if we can't find the key, we will return the random name in the as_randomNames array of string.

Then, we created the LocalHiScore script to load and save our user data. In this script, we created SetMaxUser(maxUser : int) to get the maximum number of users to display on the menu, and called the LoadGameLocal() function. This function will load the user data, and then store the data to the array. The function also gets the minimum score from the user data and stores this score for comparing when the player submits the score.

In the LocalHiScore script, we also created SaveGame (scores : int, name : String) to save the player's final score to the local machine and the SortUser (array : UsersData[]) function to sort the user data before saving. In the SaveGame (scores : int, _name : String) function, first we checked whether the player's submitted score is higher than the minimum score from the user data or not. If it isn't, we don't add the new score to the user data. On the other hand, if the submitted score is higher than the minimum score, the old minimum score will be removed, and the new score will be added to the new user data. Then, we call the SortUser (array : UsersData[]) function. This function will sort the array of the UsersData from the highest to lowest user score.

Finally, we go back to the HiScore script to add the script that will display our local high score.

Classified Intel

In this section, we have used the PlayerPrefs to load and save the user data (name and score) to our local machine. The PlayerPrefs class is basically used for saving or loading the data by using the key string to identify each piece of data. We can set the value that we want to store and load to string, float, or int type.

For storing or saving the data, we can use PlayerPrefs.SetInt(Key, Value), PlayerPrefs.SetFloat(Key, Value), or PlayerPrefs.SetString(Key, Value). We can create the new data by giving a different Key for each saving data. On the other hand, if we want to replace the old data with the new data, we just have to set the same Key to the new data that we will save.

For loading the data, we will use PlayerPrefs.GetInt(Key), PlayerPrefs.GetFloat(Key), or PlayerPrefs.GetString(Key) to get value that we have stored. We can also check whether the data is already stored in this machine or not by using PlayerPrefs.HasKey(Key).

We already talked about how to save and load the data from PlayerPref, but we didn't talk about how to remove it. We can use PlayerPrefs.Delete(Key) to remove the data that we don't want by specifying the Key. Also, if we want to remove all the data that we have saved, we can use PlayerPrefs.DeleteAll().

Note

We can also go to the following website for more details on the PlayerPrefs class:

http://unity3d.com/support/documentation/ScriptReference/PlayerPrefs.html.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.126.199