Unity中使用序列化來保存本地遊戲數據
遊戲中常常會遇到需要保存玩家數據的情況,如果是簡單的數據,unity已經提供一種非常方便的數據存儲的方式:PlayerPrefs類。但是這樣存儲簡單的數據還好,如果用來存複雜和大量數據的話,就比較麻煩,通常可能大家會選擇Xml或者Json等,我這裏介紹另外一種比較方便的保存方式:
通過序列化(Serialize)來保存玩家的數據,相比xml來說,我覺得代碼更加簡單。
實例:
比如現在在做一款三消遊戲,遊戲需要保存玩家的數據,包括音效,音樂的開關,生命值,金幣數量,已經達到的關卡,和每一關獲得的星星數量和分數,假設現在這些數據都要保存在本地,
通常我會先寫好一個玩家類,定義好這些數據
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine;
//玩家每一關獲得的星星和分數
[System.Serializable]
public struct PlayerLevelRecord
{
public int starCount;///<星星數量
public int playerScore;///<分數
}
//玩家數據類
[System.Serializable]
public class PlayerData
{
//遊戲設置
public bool isMusicOn=true;///<是否打開音樂
public bool isSoundOn=true;///<是否打開音效
//玩家數據
public int life=5;///<生命
public int reachedLevel=1;///<達到的關卡
public List<PlayerLevelRecord> list_levelScore=new List<PlayerLevelRecord>();///<每關的星星和分數
//構造函數
public PlayerData()
{
PlayerLevelRecord record = new PlayerLevelRecord();
record.starCount = 0;
record.playerScore = 0;
list_levelScore.Add(record);
}
}
定義好簡單的類和數據以後,就是保存和讀取數據了
public class PlayerDataOperator : MonoBehaviour
{
public PlayerData playerData;///<玩家對象
private string path;///<文件的路徑
// Use this for initialization
void Awake () {
//在遊戲剛剛運行時,根據平臺,選擇好對應的路徑
SetPath();
}
//讀取玩家的數據
public PlayerData LoadPlayerData()
{
//如果路徑上有文件,就讀取文件
if (File.Exists(path))
{
//讀取數據
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(path, FileMode.Open);
playerData = (PlayerData)bf.Deserialize(file);
file.Close();
}
//如果沒有文件,就new出一個PlayerData
else
{
playerData = new PlayerData();
}
return playerData;
}
//保存玩家的數據
public void SavePlayerData()
{
//保存數據
BinaryFormatter bf = new BinaryFormatter();
if (File.Exists(path))
{
File.Delete(path);
}
FileStream file = File.Create(path);
bf.Serialize(file, playerData);
file.Close();
}
//設置文件的路徑,在手機上運行時Application.persistentDataPath這個路徑纔是可以讀寫的路徑
void SetPath()
{
//安卓平臺
if (Application.platform==RuntimePlatform.Android)
{
path = Application.persistentDataPath + "/playerData.gd";
}
//windows編輯器
else if (Application.platform==RuntimePlatform.WindowsEditor)
{
path = Application.streamingAssetsPath + "/playerData.gd";
}
}
}
寫了不少代碼,其實真正核心的保存和讀取的代碼分別也就4-5行,非常簡單。
特別注意,如果要保存的數據中有一些不支持Unity序列化的話,可能就無法保存了,比如Dictionary容器,二維數組等等,需要通過其他辦法來解決。
如果上面有什麼錯誤的地方,請大家大膽指正。