您的位置:首页 > 移动开发 > Unity3D

Unity3D PlayerPrefs 存取二进制数据

2017-05-20 17:12 330 查看
Unity PlayerPrefs 提供了字典存储接口,但没有针对二进制数据的操作。如果希望存储二进制数据bytes,就需要把bytes[]和string进行转化,然后利用PlayerPrefs存储string的方式来达到目的。所以,问题转化成,string和bytes[]的互相转换操作。

可以参看这一篇文章, C# byte[]数组和string的互相转化 (四种方法)。四种方法,只有一种可以正确转换数据。

string    dataStr    = PlayerPrefs.GetString(Key);
byte[]   dataBytes = Convert.FromBase64String(dataStr);

string    dataStr    = Convert.ToBase64String(bytes);
PlayerPrefs.SetString(key,  dataStr);


存储二进制数据,一方面可以数据加密,一方面相当于对象的序列化和反序列化操作。这样就可以提供一个通用的数据存储接口,来持久化对象数据。

public static class PlayerPrefsManager
{
public interface IDataHandler
{
string GetSaveKey ();
void   OnWriteData(NetStream writer);
void   OnReadData (NetStream reader);
}

/// <summary>
/// 保存所有模块数据处理对象
/// </summary>
private static Dictionary<string, IDataHandler> handlerDict = new Dictionary<string, IDataHandler>();

/// <summary>
/// 注册模块数据处理
/// </summary>
public static void RegisterHandler(IDataHandler dataHandler)
{
handlerDict.Add(dataHandler.GetSaveKey(), dataHandler);
}

/// <summary>
/// 保存所有模块数据到PlayerPrefs
/// </summary>
public static void Save()
{
foreach (KeyValuePair<string, IDataHandler> kv in handlerDict)
{
NetStream writer  = new NetStream();
kv.Value.OnWriteData(writer);
string    dataStr = Convert.ToBase64String(writer.GetBuffer());
writer.Close();

PlayerPrefs.SetString(kv.Key, dataStr);
}

PlayerPrefs.Save();
}

/// <summary>
/// 保存指定模块数据到PlayerPrefs
/// </summary>
/// <param name="key">模块数据标识</param>
public static void Save(string key)
{
IDataHandler handler;

if (handlerDict.TryGetValue(key, out handler))
{
NetStream writer  = new NetStream();
handler.OnWriteData(writer);
string    dataStr = Convert.ToBase64String(writer.GetBuffer());
writer.Close();

PlayerPrefs.SetString(key, dataStr);
PlayerPrefs.Save();
}
else
{
DebugUtil.LogError("GameData Save not found key = {0}", key);
}
}

/// <summary>
/// 保存模块数据
/// </summary>
public static void Save(this IDataHandler handler)
{
Save(handler.GetSaveKey());
}

/// <summary>
/// 初始化保存的数据
/// </summary>
public static void Load()
{
foreach (KeyValuePair<string, IDataHandler> kv in handlerDict)
{
string    dataStr = PlayerPrefs.GetString(kv.Key);
NetStream reader  = new NetStream(Convert.FromBase64String(dataStr));

if (reader.GetLength() > 0)
{
kv.Value.OnReadData(reader);
}

reader.Close();
}
}
}


依赖于一个内存数据流的对象类,C# 二进制字节流读写封装。这个PlayerPrefsManager类,模拟了二进制数据的载入和写入,只不过最终的持久化是依赖 PlayerPrefs的存储能力的。使用起来有点像网游一般的数据处理方式。

给出一个使用例子:

public class GameSaveData : PlayerPrefsManager.IDataHandler
{
public static GameSaveData instance = new GameSaveData();

private GameSaveData()
{
NotificationCenter.OnEnterStation += OnEnterStation;
NotificationCenter.OnGoldChanged  += OnGoldChanged;
}

public int gameGolds    = 0;

public string GetSaveKey()
{
return "GameSaveData";
}

public void OnReadData(NetStream reader)
{
this.gameGolds    = reader.ReadInt16();
}

public void OnWriteData(NetStream writer)
{
writer.WriteInt16((short) this.gameGolds);
}

private void OnEnterStation()
{
PlayerPrefsManager.Save();
}

private void OnGoldChanged(GoldGetType gt, int num)
{
this.gameGolds += num;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: