在Minecraft中,保存了很多块的位置。
我将通过使用PlayerPrefs以自己的方式尝试。
int i, ObjectType;
Vector3 Pos;
// ObjectType is a block ID such as grass block or iron block in Minecraft.
// Pos is a position of each blocks
PlayerPrefs.SetString("object" + i, ObjectType + ", " + Pos);
但是,在处理数百个数据时,据说不建议使用PlayerPrefs。我只知道将数据保存在PlayerPrefs中。
在这种情况下我该怎么办?
答案 0 :(得分:2)
PlayerPref旨在存储和访问游戏会话(如设置)之间的玩家偏好。您只能使用它来保存字符串,整数或浮点数据类型。是的,不应将其用于存储所需的大量数据。如果您决定添加更多级别怎么办?最后,您将在一个PlayerPrefs词典对象中获得所有级别,设置和其他游戏信息,该对象很难维护,效率低下并且易于用户修改。
您应该使用有关级别,块对象列表等的信息来制作类/结构,然后将对象序列化为二进制文件,然后可以将其作为文件保存在本地设备中,或流式传输到在线服务器。我建议观看这个Unity Live Session教程:Persistence - Saving and Loading Data(对于初学者)。
您还可以将游戏数据本地或在线存储在数据库中。
答案 1 :(得分:1)
我建议您使用例如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
}
}
有关更多详细信息,请参见Saving and Loading Data: XmlSerializer。