Я бы рекомендовал использовать, например, файл XML
для хранения всей структуры ваших данных
Блок : для хранения данных одного блока.Вы можете расширить это по желанию, например, с помощью перечисления BlockType
или цвета материала и т. Д. (Все, что можно сериализовать)
using System;
using System.Xml.Serialization;
using UnityEngine;
[Serializable]
public class Block
{
[XmlAttribute] public string Name;
[XmlElement] public Vector3 Position;
// for the serializer a parameter-free default constructor is mandatory
public Block() { }
public Block(string name, Vector3 position)
{
Name = name;
Position = position;
}
}
BlocksData : для хранения данных всех блоков и обработкиXML-файл IO
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
using UnityEngine;
[XmlRoot("BlocksData")]
[Serializable]
public class BlocksData
{
[XmlArray]
[XmlArrayItem]
public List<Block> Blocks = new List<Block>();
public void Save(string filePath)
{
var serializer = new XmlSerializer(typeof(BlocksData));
using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
serializer.Serialize(stream, this);
}
}
public static BlocksData Load(string filePath)
{
if (!File.Exists(filePath))
{
Debug.LogWarning("File not found: " + filePath);
}
var serializer = new XmlSerializer(typeof(BlocksData));
using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
return serializer.Deserialize(stream) as BlocksData;
}
}
}
И, наконец, класс контроллера, который использует этот BlocksData
и что-то с ним делает.Например,
using System.Collections.Generic;
using System.IO;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
public class BlocksController : MonoBehaviour
{
private const string FILE_EXTENSION = ".xml";
// fileName of the XML file (without extension)
public string FileName;
// prefab to be spawned for each block
public GameObject BlockPrefab;
// blocks in the scene
public List<Transform> SceneBlocks;
// blocks in the data
public BlocksData BlocksData;
private static string Folder
{
get
{
#if UNITY_EDITOR
return Application.streamingAssetsPath;
#else
return Application.persistentDataPath;
#endif
}
}
private string FilePath
{
get
{
return Path.Combine(Folder, FileName + FILE_EXTENSION);
}
}
[ContextMenu("Load Blocks")]
public void LoadBlocks()
{
// Load from file
BlocksData = BlocksData.Load(FilePath);
// remove current scene blocks
foreach (var sceneBlock in SceneBlocks)
{
// Have to se destroyImmediate in editmode
if (Application.isEditor && !Application.isPlaying)
{
DestroyImmediate(sceneBlock.gameObject);
}
else
{
Destroy(sceneBlock.gameObject);
}
}
// instantiate and setup prefab foreach block in data
foreach (var block in BlocksData.Blocks)
{
var newBlock = Instantiate(BlockPrefab, block.Position, Quaternion.identity, transform);
newBlock.name = block.Name;
// don't forget to add it to the list of sceneBlocks
SceneBlocks.Add(newBlock.transform);
}
}
[ContextMenu("Save Blocks")]
public void SaveBlocks()
{
// clear current data list
BlocksData.Blocks.Clear();
// add a block data foreach block in scene
foreach (var sceneBlock in SceneBlocks)
{
BlocksData.Blocks.Add(new Block(sceneBlock.name, sceneBlock.position));
}
// finally write to file
BlocksData.Save(FilePath);
#if UNITY_EDITOR
AssetDatabase.Refresh();
#endif
}
}
см. Сохранение и загрузка данных: XmlSerializer для получения более подробной информации.