MaksimMaltsev
Member
- Joined
- Mar 29, 2021
- Messages
- 9
- Programming Experience
- 1-3
Hi all. I am making a game like minecraft. I need to keep the world when the player exits the game. Chunk (it is a place 16 by 16 blocks) and world contain a lot datas, that don't serialize can. so i have created classes WorldData and ChunkData, that contain only serializable varibles. But i have a error when world is serialized: XmlException: Root element is missing. This is the code:
WorldData:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Xml.Serialization;
public class WorldData{
public static XmlSerializableDictionary<Vector2, ChunkData> bloksData = new XmlSerializableDictionary<Vector2, ChunkData>();//deserialized dictionary
public static XmlSerializableDictionary<VectorConventer, ChunkData> bloksConvertData = new XmlSerializableDictionary<VectorConventer, ChunkData>();//serializible dictionary
//get deserialized world <Vector2, ChunkData>
public static XmlSerializableDictionary<Vector2, ChunkData> Deserialization(){
XmlSerializer WorldXML = new XmlSerializer(typeof(XmlSerializableDictionary<VectorConventer, ChunkData>));
using (FileStream fs = new FileStream("New_World.xml", FileMode.OpenOrCreate)){
bloksConvertData = (XmlSerializableDictionary<VectorConventer, ChunkData>)WorldXML.Deserialize(fs); //Error. XmlException: Root element is missing.
}
foreach(var item in bloksData){
bloksConvertData[new VectorConventer(item.Key)] = item.Value;
}
return bloksData;
}
//serialisation
static void SaveWorld(){
foreach(var item in bloksData){
VectorConventer keyVec = new VectorConventer(item.Key);
bloksConvertData[keyVec] = item.Value;
}
XmlSerializer WorldXML = new XmlSerializer(typeof(XmlSerializableDictionary<VectorConventer, ChunkData>));
using (FileStream fs = new FileStream("New_World.xml", FileMode.OpenOrCreate)){
WorldXML.Serialize(fs, bloksConvertData);
}
}
//add new chunk to save
public static void AddNewChunk(Vector2 position){
bloksData.Add(position, new ChunkData());
}
}
CunkData:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using System.IO;
using System.Runtime.Serialization;
using System.Xml.Serialization;
[Serializable]
public class ChunkData
{
public ChunkData(){}
public BlockType [] bloks = new BlockType [165888];
public bool isGenetated;
public float posX;
public float posZ;
public void SetValues(BlockType [ , , ] bloks3d, Vector2 position){
bloks = ToSimpleArray(bloks3d);
posX = position.x;
posZ = position.y;
}
public BlockType [ , , ] GetArray(){
return To3dArray(bloks);
}
//to three dimensional array
private static BlockType [ , , ] To3dArray(BlockType [] Array){
BlockType [ , , ] resultArray = new BlockType [18, 512, 18];
for(int i = 0; i < 18; i++){
for(int j = 0; j < 512; j++){
for(int k = 0; k < 18; k++){
resultArray[i, j, k] = Array[i*512*18 + j*18 + k];
}
}
}
return resultArray;
}
//to one dimensional array
private static BlockType [] ToSimpleArray(BlockType [ , , ] Array)
{
BlockType [] resultArray = new BlockType [18 * 512 * 18];
int index = 0;
BlockType [] SimpleArray = new BlockType [27];
for(int i = 0; i < 18; i++){
for(int j = 0; j < 512; j++){
for(int k = 0; k < 18; k++){
SimpleArray[index] = Array[i, j, k];
index++;
}
}
}
return resultArray;
}
}
World:
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;
using UnityEngine;
public class World : MonoBehaviour
{
public static Dictionary<Vector2, Chunck> chunks = new Dictionary<Vector2, Chunck>();
public List <Vector2> toGenerate;
public List <Vector2> toDelete;
public static XmlSerializableDictionary<Vector2, Chunck> loadedChuncks = new XmlSerializableDictionary<Vector2, Chunck>();
//<...>
void Start() //called when the game starts
{
LoadWorld();
//<...>
}
public void LoadWorld(){
Dictionary<Vector2, ChunkData> world = WorldData.Deserialization();
foreach (var item in world)
{
loadedChuncks.Add(item.Key, new Chunck());
loadedChuncks[item.Key].Data = item.Value;
loadedChuncks[item.Key].SetValues();
}
}
//<...>
}
Chunck:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Chunck : MonoBehaviour
{
public ChunkData Data;
public BlockType [ , , ] bloks = new BlockType [18, 512, 18]; //data of the blocks in the chunk
public Vector2 Position = new Vector2();
//<...>
//generation
public void ChunckGeneration(){
//<...>
}
public void Optimize() //build voxels
{
//<...>
}
//set data to serialisation
void ChunckToSave(){
Data.SetValues(this.bloks, Position);
}
//get data
public void SetValues(){
this.bloks = Data.GetArray();
this.isGenetated = false;
}
}