Unity中二维数组列表的序列化问题求助
Hey Rik, let's work through your 2D array serialization problem together! It sounds like your main issue is getting those wallConfig0 to wallConfig3 2D arrays serialized properly, plus wrapping them into a list alongside your existing RoomDataList structure. Here's a step-by-step guide tailored to your scenario:
1. Why Your 2D Arrays Aren't Serializing
First up, if you're using Unity's built-in JsonUtility, it doesn't support multi-dimensional arrays like int[,] out of the box—it only handles 1D arrays and List<T> types. That's exactly why your other fields work but the wall configs don't. If you're using a different serializer (like Newtonsoft.Json), it might support 2D arrays, but let's cover both practical approaches.
2. Solution 1: Switch to Nested Lists (No Third-Party Libraries)
The easiest fix without adding external tools is replacing your 2D arrays with nested List<List<int>>—these serialize seamlessly with JsonUtility and most other serializers.
Adjust Your RoomData Structure
Update your RoomData class to use nested lists, and add a property to group all four wall configs into a single list for easy serialization:
[Serializable] public class RoomData { // Keep your other existing serializable fields here public List<List<int>> wallConfig0; public List<List<int>> wallConfig1; public List<List<int>> wallConfig2; public List<List<int>> wallConfig3; // A list containing all four wall configs for straightforward serialization public List<List<List<int>>> AllWallConfigs { get { return new List<List<List<int>>> { wallConfig0, wallConfig1, wallConfig2, wallConfig3 }; } set { if (value?.Count >= 4) { wallConfig0 = value[0]; wallConfig1 = value[1]; wallConfig2 = value[2]; wallConfig3 = value[3]; } } } }
Serialize with Unity's JsonUtility
Since your RoomDataList is already marked [Serializable], you can serialize it directly:
// Create and populate your room data list var myRoomList = new RoomDataList(); // Add RoomData entries with populated wallConfig lists... // Serialize to human-readable JSON string jsonOutput = JsonUtility.ToJson(myRoomList, prettyPrint: true); // Deserialize back to your data structure RoomDataList deserializedList = JsonUtility.FromJson<RoomDataList>(jsonOutput);
3. Solution 2: Keep 2D Arrays with Newtonsoft.Json
If you need to stick with int[,] 2D arrays, use Newtonsoft.Json (a flexible, widely-used serializer that works great in Unity—you can add it via the Unity Package Manager under "Registry > Newtonsoft.Json").
Update Your Classes
You don't need to change your 2D arrays—just use Newtonsoft's serialization methods:
using Newtonsoft.Json; [Serializable] public class RoomDataList { public List<RoomData> roomDataList = new List<RoomData>(); } [Serializable] public class RoomData { public int[,] wallConfig0; public int[,] wallConfig1; public int[,] wallConfig2; public int[,] wallConfig3; // Optional: Expose all four wall configs as a single array in the JSON output [JsonProperty("wallConfigs")] public int[][,] AllWallConfigs => new int[][,] { wallConfig0, wallConfig1, wallConfig2, wallConfig3 }; }
Serialize/Deserialize with Newtonsoft.Json
// Populate your room data list var myRoomList = new RoomDataList(); // Add RoomData entries with filled 2D arrays... // Serialize to formatted JSON string jsonOutput = JsonConvert.SerializeObject(myRoomList, Formatting.Indented); // Deserialize back to your original structure RoomDataList deserializedList = JsonConvert.DeserializeObject<RoomDataList>(jsonOutput);
4. Bonus: Hybrid Approach (Keep 2D Arrays, Use Unity JsonUtility)
If you can't use Newtonsoft.Json, you can add serialization callbacks to convert 2D arrays to nested lists behind the scenes. This lets you keep using 2D arrays in your code while the serializer works with compatible list types:
[Serializable] public class RoomData : ISerializationCallbackReceiver { // These nested lists will be serialized by JsonUtility public List<List<int>> serializedWallConfig0; public List<List<int>> serializedWallConfig1; public List<List<int>> serializedWallConfig2; public List<List<int>> serializedWallConfig3; // Your actual 2D arrays (marked non-serialized so JsonUtility ignores them) [System.NonSerialized] public int[,] wallConfig0; [System.NonSerialized] public int[,] wallConfig1; [System.NonSerialized] public int[,] wallConfig2; [System.NonSerialized] public int[,] wallConfig3; // Convert arrays to lists right before serialization public void OnBeforeSerialize() { serializedWallConfig0 = Convert2DArrayToList(wallConfig0); serializedWallConfig1 = Convert2DArrayToList(wallConfig1); serializedWallConfig2 = Convert2DArrayToList(wallConfig2); serializedWallConfig3 = Convert2DArrayToList(wallConfig3); } // Convert lists back to arrays right after deserialization public void OnAfterDeserialize() { wallConfig0 = ConvertListTo2DArray(serializedWallConfig0); wallConfig1 = ConvertListTo2DArray(serializedWallConfig1); wallConfig2 = ConvertListTo2DArray(serializedWallConfig2); wallConfig3 = ConvertListTo2DArray(serializedWallConfig3); } // Helper conversion methods private List<List<T>> Convert2DArrayToList<T>(T[,] array) { if (array == null) return null; var list = new List<List<T>>(); for (int i = 0; i < array.GetLength(0); i++) { var row = new List<T>(); for (int j = 0; j < array.GetLength(1); j++) { row.Add(array[i, j]); } list.Add(row); } return list; } private T[,] ConvertListTo2DArray<T>(List<List<T>> list) { if (list == null || list.Count == 0) return null; int rows = list.Count; int cols = list[0].Count; var array = new T[rows, cols]; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { array[i, j] = list[i][j]; } } return array; } }
内容的提问来源于stack exchange,提问作者Rik

