C# 字节数组和保存的游戏
C# Bytes array and Saved Games
我需要一点帮助。我正在 Unity3D 中制作一个足够简单的游戏,我想使用 SavedGames(Google 游戏服务)保存一些变量(黄金、库存等)。
我已经读过它,显然我必须将数据作为字节数组发送到 Google Games。所以我也读过字节数组,但我不明白。关于它的每篇文章或问题似乎都假定了一定程度的知识(我显然没有)。我卡住了。
我的问题是:如何从 int 变量到字节数组?
例如:
用户拥有 52 个金币 (int gold_coins)、三个治疗药水 (int heal_pot) 和 4 个法力药水 (int mana_pot)。我想将这三个变量放入一个字节数组中,当用户保存游戏状态时,我可以将其添加到 Google。然后,当他再次加载它时,字节数组中的数据需要返回到整数。 (当我首先看到如何将它们放入数组时,我可能会自己弄清楚最后一部分)。
我希望你们能给我解释一下,或者给我指明正确的方向。与此同时,祝你周一愉快。谢谢。
编辑 2:所以,我知道了:
在 SaveData.cs 中:
using UnityEngine;
using ProtoBuf;
[ProtoContract]
public enum DataType{
pu0 = 0; //gold in game
pu1 = 1; //heal_pot ingame
pu2 = 2; //mana_pot ingame
}
[ProtoContract]
public class PBSaveData{
[ProtoMember(1)]
public DataType type;
[ProtoMember(2)]
public int amountStored;
}
在 PBGameState.cs 中:
using ProtoBuf;
[ProtoContract]
public class PBGameState{
[ProtoMember(1)]
public PBSaveData[] saveData;
}
在SaveManager.cs中:
using ProtoBuf;
using System.IO;
public class SaveManager{
private string gameStateFilePath;
void SaveState(){
PBStateGame state = new PBGameState();
state.saveData = new PBSaveData[3];
for (int i=0; i<state.saveData.Length{
state.saveData[i] = new PBSaveData();
state.saveData[i].type = "pu" + (i+1);
state.saveData[i].amoundStore = its[i] //its is where is store my inventory locally.
}
using(var ms = new MemoryStream()){
// Serialize the data to the stream
Serializer.Serialize(ms, state);
byteArray = ms.ToArray();
}
// Create a texture the size of the screen, RGB24 format
int width = Screen.width;
int height = Screen.height;
Texture2D Screenshot = new Texture2D( width, height, TextureFormat.RGB24, false );
// Read screen contents into the texture
Screenshot.ReadPixels( new Rect(0, 0, width, height), 0, 0 );
Screenshot.Apply();
long TotalPlayedTime = 20000;
string currentSaveName = "sg";
string description = "Modified data at: " + System.DateTime.Now.ToString("MM/dd/yyyy H:mm:ss");
GooglePlaySavedGamesManager.ActionGameSaveResult += ActionGameSaveResult;
GooglePlaySavedGamesManager.instance.CreateNewSnapshot(currentSaveName, description, Screenshot, byteArray, TotalPlayedTime);
}
}
void LoadState()
{
PBGameState state = new PBGameState ();
using(var ms = new MemoryStream(byteArray)){
state = Serializer.Deserialize<PBGameState> (ms);
AndroidMessage.Create ("loadtest", state.saveData[0].amountStored.ToString());
}
if (state.saveData != null) {
// Iterate through the loaded game state
for (int i = 0; i < state.saveData.Length; i++) {
its [i] = state.saveData [i].amountStored;
}
} else {
AndroidMessage.Create ("loadtest", "notworking");
}
}
所以保存显然有效,但是当我重新启动游戏时,数据似乎没有加载(我有一个启动加载过程的按钮)并且库存是空的...
知道我做错了什么吗?谢谢:)
这是教程的 link:
tuto
有人要吗?
您需要做的是:
- 有一个对象来存储您要保存的值,例如 class 名称
GameState
或其他任何东西
- 序列化你这个class的实例,这是在你的字节数组
中转换你的实例的过程
- 当你想从字节数组中取回你的值时,你需要反序列化你的字节数组
见实例Convert any object to a byte[]
另见 https://msdn.microsoft.com/en-us/library/ms233843.aspx
回答第二个问题:
不使用 FileStream
,而是使用 MemoryStream
:
// New MemoryStream, used just like any other stream, but without file (all in memory)
var ms = new MemoryStream();
// Serialize the data to the stream
Serializer.Serialize(fs, state);
// Get back the byte array from the stream
// Doesn't matter where the Position is on the stream, this'll return the
// whole MemoryStream as a byte array
var byteArray = ms.ToArray();
首先,将您的变量以某种特定格式(例如用分号分隔)保存到字符串中。然后,使用一些编码将其转换为 byte[]。
string saveState = String.Format("{0};{1};{2}", gold_coins, heal_pot, mana_pot);
byte[] saveBytes = Encoding.UTF8.GetBytes(saveState);
之后你就可以随心所欲地使用byte[]了。要解析保存的数据:
string[] retrievedData = Encoding.UTF8.GetString(saveBytes).Split(';'); //saveBytes is the Byte[] you get from the cloud.
int gold = int.Parse(retrievedData[0]);
解析后的数组将按照您将它们放入字符串的顺序包含项目。
但是 这只是一种简单的(完全不推荐)序列化方式)。有关更好的方法,请参阅@ken2k 的回答。
我需要一点帮助。我正在 Unity3D 中制作一个足够简单的游戏,我想使用 SavedGames(Google 游戏服务)保存一些变量(黄金、库存等)。 我已经读过它,显然我必须将数据作为字节数组发送到 Google Games。所以我也读过字节数组,但我不明白。关于它的每篇文章或问题似乎都假定了一定程度的知识(我显然没有)。我卡住了。 我的问题是:如何从 int 变量到字节数组?
例如: 用户拥有 52 个金币 (int gold_coins)、三个治疗药水 (int heal_pot) 和 4 个法力药水 (int mana_pot)。我想将这三个变量放入一个字节数组中,当用户保存游戏状态时,我可以将其添加到 Google。然后,当他再次加载它时,字节数组中的数据需要返回到整数。 (当我首先看到如何将它们放入数组时,我可能会自己弄清楚最后一部分)。
我希望你们能给我解释一下,或者给我指明正确的方向。与此同时,祝你周一愉快。谢谢。
编辑 2:所以,我知道了:
在 SaveData.cs 中:
using UnityEngine;
using ProtoBuf;
[ProtoContract]
public enum DataType{
pu0 = 0; //gold in game
pu1 = 1; //heal_pot ingame
pu2 = 2; //mana_pot ingame
}
[ProtoContract]
public class PBSaveData{
[ProtoMember(1)]
public DataType type;
[ProtoMember(2)]
public int amountStored;
}
在 PBGameState.cs 中:
using ProtoBuf;
[ProtoContract]
public class PBGameState{
[ProtoMember(1)]
public PBSaveData[] saveData;
}
在SaveManager.cs中:
using ProtoBuf;
using System.IO;
public class SaveManager{
private string gameStateFilePath;
void SaveState(){
PBStateGame state = new PBGameState();
state.saveData = new PBSaveData[3];
for (int i=0; i<state.saveData.Length{
state.saveData[i] = new PBSaveData();
state.saveData[i].type = "pu" + (i+1);
state.saveData[i].amoundStore = its[i] //its is where is store my inventory locally.
}
using(var ms = new MemoryStream()){
// Serialize the data to the stream
Serializer.Serialize(ms, state);
byteArray = ms.ToArray();
}
// Create a texture the size of the screen, RGB24 format
int width = Screen.width;
int height = Screen.height;
Texture2D Screenshot = new Texture2D( width, height, TextureFormat.RGB24, false );
// Read screen contents into the texture
Screenshot.ReadPixels( new Rect(0, 0, width, height), 0, 0 );
Screenshot.Apply();
long TotalPlayedTime = 20000;
string currentSaveName = "sg";
string description = "Modified data at: " + System.DateTime.Now.ToString("MM/dd/yyyy H:mm:ss");
GooglePlaySavedGamesManager.ActionGameSaveResult += ActionGameSaveResult;
GooglePlaySavedGamesManager.instance.CreateNewSnapshot(currentSaveName, description, Screenshot, byteArray, TotalPlayedTime);
}
}
void LoadState()
{
PBGameState state = new PBGameState ();
using(var ms = new MemoryStream(byteArray)){
state = Serializer.Deserialize<PBGameState> (ms);
AndroidMessage.Create ("loadtest", state.saveData[0].amountStored.ToString());
}
if (state.saveData != null) {
// Iterate through the loaded game state
for (int i = 0; i < state.saveData.Length; i++) {
its [i] = state.saveData [i].amountStored;
}
} else {
AndroidMessage.Create ("loadtest", "notworking");
}
}
所以保存显然有效,但是当我重新启动游戏时,数据似乎没有加载(我有一个启动加载过程的按钮)并且库存是空的... 知道我做错了什么吗?谢谢:)
这是教程的 link: tuto
有人要吗?
您需要做的是:
- 有一个对象来存储您要保存的值,例如 class 名称
GameState
或其他任何东西 - 序列化你这个class的实例,这是在你的字节数组 中转换你的实例的过程
- 当你想从字节数组中取回你的值时,你需要反序列化你的字节数组
见实例Convert any object to a byte[]
另见 https://msdn.microsoft.com/en-us/library/ms233843.aspx
回答第二个问题:
不使用 FileStream
,而是使用 MemoryStream
:
// New MemoryStream, used just like any other stream, but without file (all in memory)
var ms = new MemoryStream();
// Serialize the data to the stream
Serializer.Serialize(fs, state);
// Get back the byte array from the stream
// Doesn't matter where the Position is on the stream, this'll return the
// whole MemoryStream as a byte array
var byteArray = ms.ToArray();
首先,将您的变量以某种特定格式(例如用分号分隔)保存到字符串中。然后,使用一些编码将其转换为 byte[]。
string saveState = String.Format("{0};{1};{2}", gold_coins, heal_pot, mana_pot);
byte[] saveBytes = Encoding.UTF8.GetBytes(saveState);
之后你就可以随心所欲地使用byte[]了。要解析保存的数据:
string[] retrievedData = Encoding.UTF8.GetString(saveBytes).Split(';'); //saveBytes is the Byte[] you get from the cloud.
int gold = int.Parse(retrievedData[0]);
解析后的数组将按照您将它们放入字符串的顺序包含项目。
但是 这只是一种简单的(完全不推荐)序列化方式)。有关更好的方法,请参阅@ken2k 的回答。