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.
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:
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
:
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; }
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); }
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]; } } }
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 }
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); } }
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; } } } } }
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(); } }
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
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.
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
}
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:
We typed our name and clicked to submit the score.
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:
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.
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.
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()
.
We can also go to the following website for more details on the PlayerPrefs
class:
http://unity3d.com/support/documentation/ScriptReference/PlayerPrefs.html.
3.133.126.199