如何将 3 维数组保存到文件中并稍后加载
How can I save 3-dimension array into file and load later
我正在尝试保存 3D 数组 具有使用 Unity 的块的位置数据,但我找不到如何保存它。
public class Block
{
public Vector3 position;
public short blockType;
public byte facing;
public Block(Vector3 pos, short t, byte f)
{
position = pos;
blockType = t;
facing = f;
}
}
这是我存储区块信息的区块class。
public Block[,,] WorldBlock = new Block[100, 10, 100];
这是我要保存的数组,里面有 100000 个块。
有很多方法可以解决这个问题。
一种方法是,例如是 Newtonsoft JSON(在最新的 Unity 版本中作为 package via the PackageManager 甚至 pre-installed)
using Newtonsoft.Json;
....
public Block[,,] WorldBlock = new Block[100, 10, 100];
private string filePath => Path.Combine(Application.persistentDataPath, "example.json");
private void Save()
{
var json = JsonConvert.SerializeObject(WorldBlock);
File.WriteAllText(filePath, json);
}
private void Load()
{
if (File.Exists(filePath))
{
var json = File.ReadAllText(filePath);
WorldBlock = JsonConvert.DeserializeObject<Block[,,]>(json);
}
var block = WorldBlock[1, 2, 3];
Debug.Log($"{block.position} - {block.blockType} - {block.facing}");
}
或者 - 因为 JSON 为你的用例浪费了很多字符 space - 你也可以实现你自己的二进制序列化,例如使用BinaryReader
and BinaryWriter
例如
[Serializable]
public class Block
{
public Vector3 position;
public short blockType;
public byte facing;
public Block(Vector3 pos, short t, byte f)
{
position = pos;
blockType = t;
facing = f;
}
public void Serialize(BinaryWriter writer)
{
writer.Write(position.x);
writer.Write(position.y);
writer.Write(position.z);
writer.Write(blockType);
writer.Write(facing);
}
public void Deserialize(BinaryReader reader)
{
position. x = reader.ReadSingle();
position. y = reader.ReadSingle();
position. z = reader.ReadSingle();
blockType = reader.ReadInt16();
facing = reader.ReadByte();
}
}
然后
private void Save()
{
using (var stream = File.Open(filePath, FileMode.OpenOrCreate, FileAccess.Write))
{
using (var writer = new BinaryWriter(stream))
{
// first store the size of each dimension
for (var i = 0; i < WorldBlock.Rank; i++)
{
writer.Write(WorldBlock.GetLength(i));
}
// then serialize all blocks
for (var i = 0; i < WorldBlock.GetLength(0); i++)
{
for (var j = 0; j < WorldBlock.GetLength(1); j++)
{
for (var k = 0; k < WorldBlock.GetLength(2); k++)
{
var block = WorldBlock[i, j, k];
block.Serialize(writer);
}
}
}
}
}
}
private void Load()
{
if (File.Exists(filePath))
{
using (var stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
{
using (var reader = new BinaryReader(stream))
{
// first get th size of each dimension
var x = reader.ReadInt32();
var y = reader.ReadInt32();
var z = reader.ReadInt32();
WorldBlock = new Block[x, y, z];
// then deserialize all blocks
for (var i = 0; i < WorldBlock.GetLength(0); i++)
{
for (var j = 0; j < WorldBlock.GetLength(1); j++)
{
for (var k = 0; k < WorldBlock.GetLength(2); k++)
{
var block = new Block();
block.Deserialize(reader);
WorldBlock[i, j, k] = block;
}
}
}
}
}
}
var exampleBlock = WorldBlock[1, 2, 3];
Debug.Log($"{exampleBlock.position} - {exampleBlock.blockType} - {exampleBlock.facing}");
}
我正在尝试保存 3D 数组 具有使用 Unity 的块的位置数据,但我找不到如何保存它。
public class Block
{
public Vector3 position;
public short blockType;
public byte facing;
public Block(Vector3 pos, short t, byte f)
{
position = pos;
blockType = t;
facing = f;
}
}
这是我存储区块信息的区块class。
public Block[,,] WorldBlock = new Block[100, 10, 100];
这是我要保存的数组,里面有 100000 个块。
有很多方法可以解决这个问题。
一种方法是,例如是 Newtonsoft JSON(在最新的 Unity 版本中作为 package via the PackageManager 甚至 pre-installed)
using Newtonsoft.Json;
....
public Block[,,] WorldBlock = new Block[100, 10, 100];
private string filePath => Path.Combine(Application.persistentDataPath, "example.json");
private void Save()
{
var json = JsonConvert.SerializeObject(WorldBlock);
File.WriteAllText(filePath, json);
}
private void Load()
{
if (File.Exists(filePath))
{
var json = File.ReadAllText(filePath);
WorldBlock = JsonConvert.DeserializeObject<Block[,,]>(json);
}
var block = WorldBlock[1, 2, 3];
Debug.Log($"{block.position} - {block.blockType} - {block.facing}");
}
或者 - 因为 JSON 为你的用例浪费了很多字符 space - 你也可以实现你自己的二进制序列化,例如使用BinaryReader
and BinaryWriter
例如
[Serializable]
public class Block
{
public Vector3 position;
public short blockType;
public byte facing;
public Block(Vector3 pos, short t, byte f)
{
position = pos;
blockType = t;
facing = f;
}
public void Serialize(BinaryWriter writer)
{
writer.Write(position.x);
writer.Write(position.y);
writer.Write(position.z);
writer.Write(blockType);
writer.Write(facing);
}
public void Deserialize(BinaryReader reader)
{
position. x = reader.ReadSingle();
position. y = reader.ReadSingle();
position. z = reader.ReadSingle();
blockType = reader.ReadInt16();
facing = reader.ReadByte();
}
}
然后
private void Save()
{
using (var stream = File.Open(filePath, FileMode.OpenOrCreate, FileAccess.Write))
{
using (var writer = new BinaryWriter(stream))
{
// first store the size of each dimension
for (var i = 0; i < WorldBlock.Rank; i++)
{
writer.Write(WorldBlock.GetLength(i));
}
// then serialize all blocks
for (var i = 0; i < WorldBlock.GetLength(0); i++)
{
for (var j = 0; j < WorldBlock.GetLength(1); j++)
{
for (var k = 0; k < WorldBlock.GetLength(2); k++)
{
var block = WorldBlock[i, j, k];
block.Serialize(writer);
}
}
}
}
}
}
private void Load()
{
if (File.Exists(filePath))
{
using (var stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
{
using (var reader = new BinaryReader(stream))
{
// first get th size of each dimension
var x = reader.ReadInt32();
var y = reader.ReadInt32();
var z = reader.ReadInt32();
WorldBlock = new Block[x, y, z];
// then deserialize all blocks
for (var i = 0; i < WorldBlock.GetLength(0); i++)
{
for (var j = 0; j < WorldBlock.GetLength(1); j++)
{
for (var k = 0; k < WorldBlock.GetLength(2); k++)
{
var block = new Block();
block.Deserialize(reader);
WorldBlock[i, j, k] = block;
}
}
}
}
}
}
var exampleBlock = WorldBlock[1, 2, 3];
Debug.Log($"{exampleBlock.position} - {exampleBlock.blockType} - {exampleBlock.facing}");
}