我們在實驗的時候,會希望再登入的時候仍保有之前User 設定的參數與數值。或是可以記錄當前的最高分等等。所以今天我將會使用 PlayerPrefs 去儲存該先前的紀錄並在剛開始執行的時候顯示之前的最高分,以及使用 Binary Formatter 的讀取與寫入來幫助我們安全的儲存資料,或是讀取先前儲存的資料等。今天實作的量比較多,我們趕緊開始吧!
首先建立一個基本的場景,如同以下:
新增一個 Empty Component 後,稱作 Dice,並且新增一個腳本 RollDice.cs
後續去新增一個 Script 。也叫做 Dice 接著開始撰寫該文本的內容。 這邊我們希望按下我們ROLL DICE button 後會隨機產生一個1~7的數值,並顯示在UI上。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class RollDice : MonoBehaviour
{
public Text scoreText;
// Roll Dice button onClick
public void rollDice()
{
int randI = Random.Range(1, 8);
scoreText.text = randI.ToString();
}
}
回到 Unity 將其所有相關的參數設定。第一步將該 Score text 拉到我們的環境中。
Button 需要去讓該文本中的 function 連結,所以就點選 Roll Dice button。 On Click 點選加號。
將 Dice 拉進到我們 function 中。
後面就去尋找我的定義的 function 的名稱。 必須要將該function 設定 public
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class RollDice : MonoBehaviour
{
public Text scoreText;
public Text highScore;
private void Start()
{
highScore.text = PlayerPrefs.GetInt("HighScore", 0).ToString();
}
// Roll Dice button onClick
public void rollDice()
{
int randI = Random.Range(1, 8);
scoreText.text = randI.ToString();
PlayerPrefs.SetInt("HighScore", randI);
}
}
highScore.text = PlayerPrefs.GetInt("HighScore", 0).ToString();
PlayerPrefs.SetInt("HighScore", number);
接下來我們執行我們的程式,就會看到我們之前的數值 6 出現在該 HighScore 下面!
// Roll Dice button onClick
public void rollDice()
{
int randI = Random.Range(1, 8);
scoreText.text = randI.ToString();
// check larger than last High score
if(randI > PlayerPrefs.GetInt("HighScore", 0))
{
PlayerPrefs.SetInt("HighScore", randI);
highScore.text = randI.ToString(); // cover the last high score!
}
}
// reset the score
public void resetScore()
{
PlayerPrefs.DeleteAll();
highScore.text = "0";
}
回到 Unity 將其 Reset button 做設定。
後面就可以實際 Demo了。 首先我們按下 Reset 重製一下我們的紀錄。
開始點選 ROLL DICE 按鈕隨機產生數值。首先出現 3 我們就顯示 High Score 為 3
接下來點選後出現 6 會覆蓋掉剛剛最高分數的 3。
如果 Random 比之前還小的數值就不會變換當前最高的分數。
關閉執行後我們可以看到原本的數值變為 0,在執行後就會看到上一次的High Score 結果又回來了。
以下是我們今天要實作的概念,我們知道說 Binary File 的可讀性低,故安全性高。
新增一個空白物件 PlayerManagement ,之後去新增一個繳本,PlayerDataManage.cs。
之後我們撰寫幾個控制去讓按鈕可以實現數值的加與減,注意到該一開始的血量為 40,並且要知道當數值已經為 0 的時候不可以再減少下去。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerDataManage : MonoBehaviour
{
public Text setHealth;
public Text setLevel;
public int showHealth = 40;
public int showLevel = 0;
public void addLevel()
{
showLevel++;
setLevel.text = showLevel.ToString();
}
public void minusLevel()
{
if(showLevel > 0)
{
showLevel--;
setLevel.text = showLevel.ToString();
}else{
setLevel.text = "0";
}
}
public void addHealth()
{
showHealth++;
setHealth.text = showHealth.ToString();
}
public void minusHealth()
{
if(showHealth > 0)
{
showHealth--;
setHealth.text = showHealth.ToString();
}else{
setHealth.text = "0";
}
}
}
指定事件到我們的環境中
這邊要注意到的地方是說 function 主要是有傳入的數值,所以說可以進行設定數值 1。也就是點選後要不然是加一或是減一。
回到 Unity 執行就會看到隨著點選該上或下會改變Health與 Level 顯示的結果。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class SaveLoadData
{
public int level;
public int health;
public float[] position;
public SaveLoadData(PlayerDataManage player) // use the constructor
{
level = player.showLevel;
health = player.showHealth;
position = new float[3]; // position is x, y, z
position[0] = player.getObjPosition.position.x;
position[1] = player.getObjPosition.position.y;
position[2] = player.getObjPosition.position.z;
}
}
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
public class SaveLoadSystem
{
public static void SavePlayer(PlayerDataManage player)
{
BinaryFormatter formatter = new BinaryFormatter();
string path = Application.persistentDataPath + "/player.fun";
FileStream stream = new FileStream(path, FileMode.Create);
SaveLoadData data = new SaveLoadData(player);
formatter.Serialize(stream, data);
stream.Close();
}
public static SaveLoadData LoadPlayer()
{
string path = Application.persistentDataPath + "/player.fun";
if(File.Exists(path))
{
BinaryFormatter formatter = new BinaryFormatter();
FileStream stream = new FileStream(path, FileMode.Open);
SaveLoadData data = formatter.Deserialize(stream) as SaveLoadData;
stream.Close();
return data;
}else{
Debug.LogWarning("Not found the file in " + path);
return null;
}
}
}
注意要記得新增Save 與 Load 按鈕。
回到 PlayerManagement 中去新增兩個 Save 與 Load 按鈕的 function。並且新增一個 ObjPosition 物件讓我們可以儲存該位置。
// save the data
public void SavePlayer()
{
SaveLoadSystem.SavePlayer(this);
}
public void LoadPlayer()
{
SaveLoadData data = SaveLoadSystem.LoadPlayer();
showLevel = data.level;
showHealth = data.health;
setLevel.text = showLevel.ToString();
setHealth.text = showHealth.ToString();
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerDataManage : MonoBehaviour
{
public Text setHealth;
public Text setLevel;
public int showHealth = 40;
public int showLevel = 0;
public Transform getObjPosition;
public void addLevel()
{
showLevel++;
setLevel.text = showLevel.ToString();
}
public void minusLevel()
{
if(showLevel > 0)
{
showLevel--;
setLevel.text = showLevel.ToString();
}else{
setLevel.text = "0";
}
}
public void addHealth()
{
showHealth++;
setHealth.text = showHealth.ToString();
}
public void minusHealth()
{
if(showHealth > 0)
{
showHealth--;
setHealth.text = showHealth.ToString();
}else{
setHealth.text = "0";
}
}
// save the data
public void SavePlayer()
{
SaveLoadSystem.SavePlayer(this);
}
public void LoadPlayer()
{
SaveLoadData data = SaveLoadSystem.LoadPlayer();
showLevel = data.level;
showHealth = data.health;
setLevel.text = showLevel.ToString();
setHealth.text = showHealth.ToString();
}
}
首先設定一下你想要的Heath = 46, Level = 4 數值。並且現在注意到我們右上角的物件的位置。
接下來點選 Save後關閉執行。
我們隨機調整一下該 ObjPosition 的位置。與剛剛的位置不同。
開始執行的時候你會發現沒什麼變動。點選 Load 就會看到剛剛我們 Save 的數值都會回來,且Obj 也回到右上角了 XD。非常的神奇!