You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中JsonUtility序列化含二维数组的类时Chunk数据丢失如何解决?

问题原因

Unity自带的JsonUtility工具本身不支持多维数组(二维数组、三维数组等)的序列化,不管你是否把多维数组封装到可序列化类内部,只要是[,]类型的数组字段,都会被JsonUtility直接忽略。你的场景中两类二维数组都无法被识别:

  • Chunk类中的int[,] tiles二维瓦片数组
  • Region类中的Chunk[,] chunks二维区块数组

解决方案

方案1:适配JsonUtility,将多维数组转一维数组做序列化兼容

JsonUtility支持一维数组的序列化,你可以对原有类做最小改造,新增一维数组作为序列化存储字段,运行时仍使用原有二维数组操作:

[Serializable]
public class Chunk
{
    // 运行时使用的二维数组,标记为不参与序列化
    [NonSerialized]
    public int[,] tiles = new int[CHUNK_SIZE, CHUNK_SIZE];
    
    // 专用于序列化存储的一维数组
    public int[] serializeTiles;

    // 序列化前调用,将二维数组转成一维
    public void BeforeSerialize()
    {
        serializeTiles = new int[CHUNK_SIZE * CHUNK_SIZE];
        for (int x = 0; x < CHUNK_SIZE; x++)
        {
            for (int y = 0; y < CHUNK_SIZE; y++)
            {
                serializeTiles[x * CHUNK_SIZE + y] = tiles[x, y];
            }
        }
    }

    // 反序列化后调用,将一维数组还原为二维
    public void AfterDeserialize()
    {
        tiles = new int[CHUNK_SIZE, CHUNK_SIZE];
        for (int x = 0; x < CHUNK_SIZE; x++)
        {
            for (int y = 0; y < CHUNK_SIZE; y++)
            {
                tiles[x, y] = serializeTiles[x * CHUNK_SIZE + y];
            }
        }
    }
}

[Serializable]
public class Region
{
    public Vector2Int location;
    // 运行时使用的二维Chunk数组,标记为不参与序列化
    [NonSerialized]
    public Chunk[,] chunks = new Chunk[REGION_SIZE, REGION_SIZE];
    
    // 专用于序列化存储的一维数组
    public Chunk[] serializeChunks;

    // 序列化前调用
    public void BeforeSerialize()
    {
        serializeChunks = new Chunk[REGION_SIZE * REGION_SIZE];
        for (int i = 0; i < REGION_SIZE; i++)
        {
            for (int j = 0; j < REGION_SIZE; j++)
            {
                chunks[i,j].BeforeSerialize();
                serializeChunks[i * REGION_SIZE + j] = chunks[i, j];
            }
        }
    }

    // 反序列化后调用
    public void AfterDeserialize()
    {
        chunks = new Chunk[REGION_SIZE, REGION_SIZE];
        for (int i = 0; i < REGION_SIZE; i++)
        {
            for (int j = 0; j < REGION_SIZE; j++)
            {
                chunks[i, j] = serializeChunks[i * REGION_SIZE + j];
                chunks[i,j].AfterDeserialize();
            }
        }
    }
}

原有序列化逻辑调整为:

Region region = new Region();
region.location = new Vector2Int(x, y);
for (int i = 0; i < REGION_SIZE; i++)
{
    for (int j = 0; j < REGION_SIZE; j++)
    {
        region.chunks[i, j] = GenerateChunk();
    }
}
// 序列化前先执行数组转换
region.BeforeSerialize();
string regionJson = JsonUtility.ToJson(region);

反序列化时先调用JsonUtility.FromJson<Region>()得到实例,再执行实例的AfterDeserialize()方法即可还原所有数据。

方案2:更换JSON序列化库

如果你不想改动原有数据结构,可以使用Newtonsoft.Json(Unity 2020+已内置该库,可直接在PackageManager中导入),该库原生支持多维数组序列化,无需修改现有Chunk、Region类,直接调用序列化方法即可:

// 直接序列化,无需其他前置处理
string regionJson = JsonConvert.SerializeObject(region);
// 反序列化调用
Region region = JsonConvert.DeserializeObject<Region>(regionJson);

内容的提问来源于stack exchange,提问作者David Meyenberg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 23:27:03