Unity数据持久化设计
Unity数据持久化一 PlayerPrefs
Unity数据持久化二 JSON
目录
前言
1. XML基础概念与Unity集成
1.1 XML简介
XML(可扩展标记语言,Extensible Markup Language),主要是以一种结构化且具有一定描述性的方式组织数据管理,常用于存储与数据传输的标记性语言,被广泛应用于不同系统之间的数据交换,XML的设计目标主要是传输数据不是显示数据。
1.2 XML在Unity中的优势
XML也具有一定的特点优势,具体如下:
| 特点 | 描述 |
|---|---|
| 易读易懂 | 数据以文本的形式进行存储,方便与调试和手动修改 |
| 结构清晰 | 层次结构清晰,适合存储于复杂数据关系 |
| 跨平台兼容 | 所有平台都支持XML解析 |
| 扩展性强 | 支持复杂数据结构和自定义格式 |
相较于JSON存储也有一定的对比性
相同点:
JSON与XML都是纯文本存储,都具有层级结构,都拥有一定的描述性。
不同点:
相较于配置简易型JSON更简单一点,且某些情况下JSON读写更快捷。
1.3 Unity中XML处理配置
在Unity中使用需要进行脚本的命名空间引用,使用的命名空间包含以下内容:
using System.Xml; //XML文件处理
using System.Xml.Serialization; //XML序列化
using System.IO; //IO文件操作
using System.Text; //编码处理
引入相应的命名空间之后进行XML文件的操作编写。
2. XML基础
使用XML需要利用序列化与反序列化进行数据存储转换
序列化与反序列化-百度百科
可以参考以上内容进行学习序列化与反序列化知识。
具体的创建和读取XML可以用一个简单的示例来呈现。
using UnityEngine;
using System.Xml;
using System.IO;
public class BasicXMLExample : MonoBehaviour
{
private string xmlFilePath;
void Start()
{
xmlFilePath = Path.Combine(Application.persistentDataPath, "basic_data.xml");
// 创建示例 XML 数据
CreateBasicXML();
// 读取并解析 XML 数据
ReadBasicXML();
}
/// <summary>
/// 手动创建 XML 文件 - 基础方法
/// </summary>
void CreateBasicXML()
{
try
{
// 创建 XML 写入设置
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true; // 启用缩进
settings.IndentChars = " "; // 缩进字符
settings.NewLineChars = "\n"; // 换行符
settings.Encoding = Encoding.UTF8; // 使用 UTF-8 编码
// 创建 XmlWriter
using (XmlWriter writer = XmlWriter.Create(xmlFilePath, settings))
{
writer.WriteStartDocument(); // 开始文档
writer.WriteStartElement("PlayerData"); // 根元素
// 写入基本玩家信息
writer.WriteElementString("Name", "张三");
writer.WriteElementString("Level", "25");
writer.WriteElementString("Experience", "12500.5");
writer.WriteElementString("Health", "85");
// 写入物品列表
writer.WriteStartElement("Inventory");
WriteInventoryItem(writer, "Sword", "1", "2.5");
WriteInventoryItem(writer, "HealthPotion", "5", "0.5");
WriteInventoryItem(writer, "GoldCoin", "150", "0.01");
writer.WriteEndElement(); // 结束 Inventory
writer.WriteEndElement(); // 结束 PlayerData
writer.WriteEndDocument(); // 结束文档
}
Debug.Log($"基础 XML 文件创建成功: {
xmlFilePath}");
}
catch (System.Exception e)
{
Debug.LogError($"创建 XML 文件失败: {
e.Message}");
}
}
/// <summary>
/// 写入物品项到 XML
/// </summary>
void WriteInventoryItem(XmlWriter writer, string name, string count, string weight)
{
writer.WriteStartElement("Item");
writer.WriteAttributeString("name", name);
writer.WriteAttributeString("count", count);
writer.WriteAttributeString("weight", weight);
writer.WriteEndElement();
}
/// <summary>
/// 读取和解析 XML 文件 - 基础方法
/// </summary>
void ReadBasicXML()
{
if (!File.Exists(xmlFilePath))
{
Debug.LogWarning("XML 文件不存在");
return;
}
try
{
// 加载 XML 文档
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(xmlFilePath);
// 获取根节点
XmlNode root = xmlDoc.DocumentElement;
// 读取基本玩家信息
string playerName = root.SelectSingleNode("Name")?.InnerText ?? "未知";
int level = int.Parse(root.SelectSingleNode("Level")?.InnerText ?? "1");
float experience = float.Parse(root.SelectSingleNode("Experience")?.InnerText ?? "0");
int health = int.Parse(root.SelectSingleNode("Health")?.InnerText ?? "100");
Debug.Log($"玩家信息 - 名称: {
playerName}, 等级: {
level}, 经验: {
experience}, 生命: {
health}");
// 读取物品列表
XmlNode inventoryNode = root.SelectSingleNode("Inventory");
if (inventoryNode != null)
{
Debug.Log("物品栏内容:");
foreach (XmlNode itemNode in inventoryNode.SelectNodes("Item"))
{
string itemName = itemNode.Attributes["name"]?.Value ?? "未知物品";
string itemCount = itemNode.Attributes["count"]?.Value ?? "0";
string itemWeight = itemNode.Attributes["weight"]?.Value ?? "0";
Debug.Log($" - {
itemName} x{
itemCount} (重量: {
itemWeight})");
}
}
}
catch (System.Exception e)
{
Debug.LogError($"读取 XML 文件失败: {
e.Message}");
}
}
}
如果需要对自定义类进行XML数据存储那就需要对自定义类进行XML序列化特性加入,如:
using System.Xml.Serialization;
[System.Serializable]
public class PlayerBasicData
{
public string playerName;
public int level;
public float experience;
public int health;
public bool isPremium;
// XmlSerializer 需要无参构造函数
public PlayerBasicData() {
}
public PlayerBasicData(string name, int level, float exp, int health, bool premium)
{
this.playerName = name;
this.level = level;
this.experience = exp;
this.health = health;
this.isPremium = premium;
}
}
public class XMLSerializerExample : MonoBehaviour
{
private string filePath;
void Start()
{
filePath = Path.Combine(Application.persistentDataPath, "player_data.xml");
// 序列化示例
SerializePlayerData();
// 反序列化示例
DeserializePlayerData();
}
/// <summary>
/// 使用 XmlSerializer 序列化对象到 XML
/// </summary>
void SerializePlayerData()
{
try
{
// 创建玩家数据对象
PlayerBasicData player = new PlayerBasicData("李四", 30, 25000.75f, 95, true);
// 创建 XmlSerializer
XmlSerializer serializer = new XmlSerializer(typeof(PlayerBasicData));
// 创建写入设置
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.Encoding = Encoding.UTF8;
// 序列化到文件
using (XmlWriter writer = XmlWriter.Create(filePath, settings))
{
serializer.Serialize(writer, player);
}
Debug.Log($"玩家数据序列化成功: {
filePath}");
}
catch (System.Exception e)
{
Debug.LogError($"序列化失败: {
e.Message}");
}
}
/// <summary>
/// 使用 XmlSerializer 从 XML 反序列化对象
/// </summary>
void DeserializePlayerData()
{
if (!File.Exists(filePath))
{
Debug.LogWarning("XML 文件不存在");
return;
}
try
{
// 创建 XmlSerializer
XmlSerializer serializer = new XmlSerializer(typeof(PlayerBasicData));
// 从文件反序列化
using (FileStream stream = new FileStream(filePath, FileMode.Open))
{
PlayerBasicData loadedPlayer = (PlayerBasicData)serializer.Deserialize(stream);
Debug.Log($"反序列化成功 - 名称: {
loadedPlayer.playerName}, " +
$"等级: {
loadedPlayer.level}, 经验: {
loadedPlayer.experience}");
}
}
catch (System.Exception e)
{
Debug.LogError($"反序列化失败: {
e.Message}");
}
}
}
加入相应的特性之后就可以对自定义对象进行XML序列化与反序列化操作了。
3. XML序列化封装
3.1 XML数据管理器
为了更好的方便使用XML实现数据的管理,如加密、压缩、版本控制和错误恢复等,可以将XML进行封装成高级的数据管理器,这样能够更有效的提供XML序列化解决方案,示例如下:
using System;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.Text;
using System.Collections.Generic;
/// <summary>
/// 高级 XML 数据管理器 - 提供完整的 XML 序列化解决方案
/// 支持加密、压缩、版本控制和错误恢复
/// </summary>
public static class AdvancedXMLDataManager
{
// 默认编码
private static Encoding defaultEncoding = Encoding.UTF8;
/// <summary>
/// XML 序列化设置
/// </summary>
[System.Serializable]
public class XMLSerializeSettings
{
public bool formatOutput = true; // 是否格式化输出
public bool includeNamespace = false; // 是否包含命名空间
public Encoding encoding = null; // 编码格式
public bool enableEncryption = false; // 启用加密
public string encryptionKey = ""; // 加密密钥
public XMLSerializeSettings()
{
encoding = Encoding.UTF8;
}
}
#region 基础序列化方法
/// <summary>
/// 序列化对象到 XML 文件
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="obj">要序列化的对象</param>
/// <param name="filePath">文件路径</param>
/// <param name="settings">序列化设置</param>
/// <returns>是否成功</returns>
public static bool SerializeToFile<T>(T obj, string filePath, XMLSerializeSettings settings = null)
{
if (obj == null)
{
Debug.LogError("序列化失败: 对象为 null");
return false;
}
try
{
settings = settings ?? new XMLSerializeSettings();
// 确保目录存在
string directory = Path.GetDirectoryName(filePath);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
// 创建 XmlSerializer
XmlSerializer serializer = new XmlSerializer(typeof(T));
// 配置 XmlWriter 设置
XmlWriterSettings writerSettings = new XmlWriterSettings();
writerSettings.Indent = settings.formatOutput;
writerSettings.IndentChars = " ";
writerSettings.Encoding = settings.encoding ?? defaultEncoding;
writerSettings.NewLineChars = "\n";
writerSettings.OmitXmlDeclaration = false;
// 序列化到文件
using (XmlWriter writer = XmlWriter.Create(filePath, writerSettings))
{
// 移除默认命名空间
XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
if (!settings.includeNamespace)
{
namespaces.Add("", "");
}
serializer.Serialize(writer, obj, namespaces);
}
Debug.Log($"XML 序列化成功: {
filePath}");
return true;
}
catch (Exception e)
{
Debug.LogError($"XML 序列化失败: {
e.Message}\n{
e.StackTrace}");
return false;
}
}
/// <summary>
/// 从 XML 文件反序列化对象
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="filePath">文件路径</param>
/// <returns>反序列化的对象</returns>
public static T DeserializeFromFile<T>(string filePath) where T : class
{
if (!File.Exists(filePath))
{
Debug.LogWarning($"XML 文件不存在: {
filePath}");
return default(T);
}
try
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (FileStream stream = new FileStream(filePath, FileMode.Open))
{
T obj = (T)serializer.Deserialize(stream);
Debug.Log($"XML 反序列化成功: {
filePath}");
return obj;
}
}
catch (Exception e)
{
Debug.LogError($"XML 反序列化失败: {
e.Message}\n{
e.StackTrace}");
return default(T);
}
}
/// <summary>
/// 序列化对象到 XML 字符串
/// </summary>
public


1355

被折叠的 条评论
为什么被折叠?



