1.代码示例:
public void SaveData(string fileName)
{
//决定存储路径
string path = Application.persistentDataPath + "/" + fileName + ".xml";
Debug.Log(Application.persistentDataPath);
//5个步骤
//1.创建我们的Xml文本
XmlDocument xml = new XmlDocument();
//2.添加固定内容
XmlDeclaration xmlDec = xml.CreateXmlDeclaration("1.0", "UTF-8", "");
xml.AppendChild(xmlDec);
//3.添加根节点
XmlElement playerInfo = xml.CreateElement("PlayerInfo");
xml.AppendChild(playerInfo);
//4.添加子节点 或者 属性相关
XmlElement name = xml.CreateElement("name");
name.InnerText = this.name;
playerInfo.AppendChild(name);
XmlElement atk = xml.CreateElement("atk");
atk.InnerText = this.atk.ToString();
playerInfo.AppendChild(atk);
XmlElement def = xml.CreateElement("def");
def.InnerText = this.def.ToString();
playerInfo.AppendChild(def);
XmlElement moveSpeed = xml.CreateElement("moveSpeed");
moveSpeed.InnerText = this.moveSpeed.ToString();
playerInfo.AppendChild(moveSpeed);
XmlElement roundSpeed = xml.CreateElement("roundSpeed");
roundSpeed.InnerText = this.roundSpeed.ToString();
playerInfo.AppendChild(roundSpeed);
//weapon
XmlElement weapon = xml.CreateElement("weapon");
XmlElement id = xml.CreateElement("id");
id.InnerText = this.weapon.id.ToString();
weapon.AppendChild(id);
XmlElement num = xml.CreateElement("num");
num.InnerText = this.weapon.num.ToString();
weapon.AppendChild(num);
playerInfo.AppendChild(weapon);
//listInt
XmlElement listInt = xml.CreateElement("listInt");
for (int i = 0; i < this.listInt.Count; i++)
{
XmlElement intNode = xml.CreateElement("int");
intNode.InnerText = this.listInt[i].ToString();
listInt.AppendChild(intNode);
}
playerInfo.AppendChild(listInt);
//itemList
XmlElement itemList = xml.CreateElement("itemList");
for (int i = 0; i < this.itemList.Count; i++)
{
XmlElement itemNode = xml.CreateElement("Item");
itemNode.SetAttribute("id", this.itemList[i].id.ToString());
itemNode.SetAttribute("num", this.itemList[i].num.ToString());
itemList.AppendChild(itemNode);
}
playerInfo.AppendChild(itemList);
//itemDic
XmlElement itemDic = xml.CreateElement("itemDic");
foreach (int key in this.itemDic.Keys)
{
//key
XmlElement intNode = xml.CreateElement("int");
intNode.InnerText = key.ToString();
itemDic.AppendChild(intNode);
//value
XmlElement itemNode = xml.CreateElement("Item");
itemNode.SetAttribute("id", this.itemDic[key].id.ToString());
itemNode.SetAttribute("num", this.itemDic[key].num.ToString());
itemDic.AppendChild(itemNode);
}
playerInfo.AppendChild(itemDic);
//5.存储
xml.Save(path);
}
}
数据结构部分:
public class Item
{
public int id;
public int num;
}
public string name;
public int atk;
public int def;
public float moveSpeed;
public float roundSpeed;
public Item weapon;
public List<int> listInt;
public List<Item> itemList;
public Dictionary<int, Item> itemDic;
都位于PlayerInfo类中 数据结构跟SaveData方法
2.归纳
-
文件路径:
- 使用
Application.persistentDataPath
获取Unity推荐的持久化数据存储路径。 - 文件名由传入的
fileName
参数和.xml
扩展名组成,确保文件是XML格式。
- 使用
-
日志输出:
- 使用
Debug.Log
输出持久化数据路径,方便开发者确认文件存储位置。
- 使用
-
XML文档创建:
- 使用
XmlDocument
类创建一个新的XML文档实例。
- 使用
-
XML声明:
- 使用
CreateXmlDeclaration
方法创建XML声明节点,指定版本、编码和独立性声明。
- 使用
-
根节点:
- 使用
CreateElement
方法创建根节点PlayerInfo
,并将其添加到XML文档中。
- 使用
-
子节点:
- 使用
CreateElement
创建子节点,并使用InnerText
属性设置节点的文本内容。 - 包括基本属性(如
name
、atk
、def
等)和复杂数据结构(如weapon
、listInt
、itemList
和itemDic
)。
- 使用
-
复杂数据结构:
-
weapon:包含
id
和num
子节点。 -
listInt:循环遍历列表
listInt
,为每个整数创建一个子节点。 -
itemList:循环遍历列表
itemList
,为每个项目创建一个带有id
和num
属性的Item
节点。 -
itemDic:循环遍历字典
itemDic
,为每个键值对创建一个int
节点和一个带有id
和num
属性的Item
节点。
-
weapon:包含
-
文件存储:
- 使用
xml.Save(path)
将构建好的XML文档保存到指定的文件路径。
- 使用
-
数据绑定:
- 通过
this.name
、this.atk
等成员变量,将当前对象的数据绑定到XML节点中。
- 通过
-
类型转换:
- 使用
ToString
方法将非字符串类型的数据转换为字符串,以便存储在XML文件中。
- 使用
-
属性设置:
- 使用
SetAttribute
方法为XML节点设置属性。
- 使用
-
文件操作:
- 代码中没有显式的错误处理或文件操作异常处理,这在实际应用中可能需要添加。
-
数据结构表示:
- 代码展示了如何将对象的复杂数据结构(如列表和字典)转换为XML格式。
-
代码的局限性:
- 代码假设所有数据都是可以被序列化为XML的,没有处理可能存在的循环引用或不支持的类型。
-
扩展性:
- 代码结构允许容易地添加更多的数据字段或修改现有的数据结构。
-
性能考虑:
- 对于大量数据的写入,XML文件操作可能会影响性能,需要考虑优化或使用更适合大量数据的存储格式。
3.Application.persistentDataPath
Application.persistentDataPath
是Unity引擎中一个非常有用的属性,它提供了一个适合存储持久化数据的目录路径。这个路径指向的目录用于存放那些需要在应用程序关闭后仍然保留的数据,比如玩家的游戏进度、配置文件、缓存数据等。以下是关于 Application.persistentDataPath
的一些详细说明:
特点
-
持久化存储:
- 存储在该路径下的数据不会因为应用程序重启而丢失,这使得它非常适合存储需要持久化的数据。
-
跨平台:
- Unity自动处理不同操作系统的路径差异,使得开发者可以使用统一的路径来访问持久化数据。
-
可写入:
- 你可以在这个路径下创建、修改和删除文件,Unity保证了这个路径在运行时是可写的。
使用场景
- 玩家数据:保存玩家的游戏进度、成就、高分等。
- 配置文件:存储游戏设置,如音量、图形选项等。
- 缓存数据:缓存下载的内容或预先加载的资源,以加快游戏加载速度。
- 本地数据库:用于存储和管理本地数据库文件。
平台差异
-
Windows:通常指向用户的文档文件夹下的Unity项目文件夹,例如
C:\Users\用户名\Documents\Unity Projects\ProjectName
。 - macOS:通常指向用户的Library/Application Support/ProjectName目录。
-
Linux:通常指向
~/.local/share/CompanyName/ProjectName
。 -
Android:指向内部存储的
/data/data/<package_name>/files
目录。 -
iOS:指向沙盒目录
Documents/
。
访问和使用
在Unity中,你可以直接通过以下方式访问 Application.persistentDataPath
:
string path = Application.persistentDataPath + "/myData.xml";
这行代码将 myData.xml
文件的路径设置为持久化数据路径加上文件名。
注意事项
- 权限:在某些平台上,特别是移动设备,你可能需要请求文件系统权限才能访问或修改文件。
- 路径操作:在构建应用程序之前,确保正确处理路径和文件操作,避免运行时错误。
- 测试:在不同的平台上测试文件的读写操作,确保跨平台兼容性。
示例代码
以下是一个简单的示例,展示如何使用 Application.persistentDataPath
保存一个文本文件:
using UnityEngine;
using System.IO;
public class DataSaver : MonoBehaviour
{
void Start()
{
string filePath = Application.persistentDataPath + "/gameData.txt";
File.WriteAllText(filePath, "Hello, Unity!");
Debug.Log("Data saved to: " + filePath);
}
}
这段代码在游戏启动时将字符串 "Hello, Unity!" 写入到 gameData.txt
文件中,并输出文件的保存路径。
总之,Application.persistentDataPath
是Unity提供的一个强大工具,使得管理持久化数据变得简单和跨平台。