IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity数据持久化之XML -> 正文阅读

[游戏开发]Unity数据持久化之XML

本博客主要记录PlayerPrefs的使用,比较长

1、什么是数据持久化

数据持久化就是将内存中的数据模型转化为存储模型,以及将存储模型转化为内存中数据模型的通称
简述:将游戏中的数据存储到硬盘,然后可以下次进游戏的时候读取硬盘中的数据到内存。

2、什么是XML

首先XML是可扩展性标记语言,被用来传输和存储数据。
具体语法和规范不再赘述,可自行查找资料。

XML资料

3、将类中属性转化为XML写法

在片描述
图1

<?xml version="1.0" encoding="UTF-8"?>
<PlayerInfo>
	<!--自己定一个xml代表 类对象数据的规则
	我们的元素节点名 就用我们的变量名命名
	-->
	<name>name哥</name>
	<atk>10</atk>
	<def>5</def>
	<moveSpeed>20</moveSpeed>
	<roundSpeed>20</roundSpeed>
	<weapon>
		<id>1</id>
		<num>1</num>
	</weapon>
	<!--当出现没有变量名的数据时 我们就用变量类型名命名-->
	<listInt>
		<int>1</int>
		<int>2</int>
		<int>3</int>
	</listInt>
	<itemList>
		<Item id="1" num="10"/>
		<Item id="2" num="20"/>
		<Item id="3" num="30"/>
		<Item id="4" num="40"/>
	</itemList>
	<itemDic>
		<int>1</int>
		<Item id="1" num="1"/>
		<int>2</int>
		<Item id="2" num="1"/>
		<int>3</int>
		<Item id="3" num="1"/>
		<!-- 另一种写法 但是建议大家都统一
		<int>4</int>
		<Item>
			<id>4</id>
			<num>1</num>
		</Item>
		-->
	</itemDic>
</PlayerInfo>

4、C#读取XML文件的方法

  • 1、XmlDocument (把数据加载到内存中,方便读取)
  • 2、XmlTextReader (以流形式加载,内存占用更少,但是是单向只读,使用不是特别方便,除非有特殊需求,否则不会使用)
  • 3、Linq 待补充
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

4.1 XmlDocument

//使用XmlDocument类读取是较方便最容易理解和操作的方法
#region 知识点一 读取xml文件信息
XmlDocument xml = new XmlDocument();
//通过XmlDocument读取xml文件 有两个API

//1.直接根据xml字符串内容 来加载xml文件
//存放在Resorces文件夹下的xml文件加载处理
TextAsset asset = Resources.Load<TextAsset>("TestXml");
print(asset.text);
//通过这个方法 就能够翻译字符串为xml对象
xml.LoadXml(asset.text);

//2.是通过xml文件的路径去进行加载
xml.Load(Application.streamingAssetsPath + "/TestXml.xml");
#endregion

#region 知识点二 读取元素和属性信息
//节点信息类
//XmlNode 单个节点信息类
//节点列表信息
//XmlNodeList 多个节点信息类

//获取xml当中的根节点,注意Root是节点的名字而不是其他意思
XmlNode root = xml.SelectSingleNode("Root");
//再通过根节点 去获取下面的子节点
XmlNode nodeName = root.SelectSingleNode("name");
//如果想要获取节点包裹的元素信息 直接 .InnerText
print(nodeName.InnerText);

XmlNode nodeAge = root.SelectSingleNode("age");
print(nodeAge.InnerText);

//对于内部有多组数据的
XmlNode nodeItem = root.SelectSingleNode("Item");
//第一种方式 直接用 中括号获取信息
print(nodeItem.Attributes["id"].Value);
print(nodeItem.Attributes["num"].Value);
//第二种方式 
print(nodeItem.Attributes.GetNamedItem("id").Value);
print(nodeItem.Attributes.GetNamedItem("num").Value);

//这里是获取 一个节点下的同名节点的方法
XmlNodeList friendList = root.SelectNodes("Friend");

//遍历方式一:迭代器遍历
//foreach (XmlNode item in friendList)
//{
//    print(item.SelectSingleNode("name").InnerText);
//    print(item.SelectSingleNode("age").InnerText);
//}
//遍历方式二:通过for循环遍历
//通过XmlNodeList中的 成员变量 Count可以得到 节点数量
for (int i = 0; i < friendList.Count; i++)
{
    print(friendList[i].SelectSingleNode("name").InnerText);
    print(friendList[i].SelectSingleNode("age").InnerText);
}
#endregion

4.2 XmlDocument总结

//1.读取XML文件
//XmlDocument xml = new XmlDocument();
//读取文本方式1-xml.LoadXml(传入xml文本字符串)
//读取文本方式2-xml.Load(传入路径)

//2.读取元素和属性
//获取单个节点 : XmlNode node = xml.SelectSingleNode(节点名)
//获取多个节点 : XmlNodeList nodeList = xml.SelectNodes(节点名)

//获取节点元素内容:node.InnerText
//获取节点元素属性:
//1.item.Attributes["属性名"].Value
//2.item.Attributes.GetNamedItem("属性名").Value

//通过迭代器遍历或者循环遍历XmlNodeList对象 可以获取到各单个元素节点

4.3 利用XmlDocument将XML转成类对象

参考图1

using System.Collections;
using System.Collections.Generic;
using System.Xml;
using UnityEngine;

public class Item
{
    public int id;
    public int num;
}

public class PlayerInfo
{
    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;

    public void LoadData(string fileName)
    {
        //加载XML文件信息
        XmlDocument xml = new XmlDocument();
        //加载
        xml.Load(Application.streamingAssetsPath + "/" + fileName + ".xml");

        //从文件中加载出具体的数据
        //加载根节点 才能加载后面的内容
        XmlNode playerInfo = xml.SelectSingleNode("PlayerInfo");
        //通过根节点 去加载具体的信息
        this.name = playerInfo.SelectSingleNode("name").InnerText;
        this.atk = int.Parse(playerInfo.SelectSingleNode("atk").InnerText);
        this.def = int.Parse(playerInfo.SelectSingleNode("def").InnerText);
        this.moveSpeed = float.Parse(playerInfo.SelectSingleNode("moveSpeed").InnerText);
        this.roundSpeed = float.Parse(playerInfo.SelectSingleNode("roundSpeed").InnerText);

        XmlNode weaponNode = playerInfo.SelectSingleNode("weapon");
        this.weapon = new Item();
        this.weapon.id = int.Parse(weaponNode.SelectSingleNode("id").InnerText);
        this.weapon.num = int.Parse(weaponNode.SelectSingleNode("num").InnerText);

        XmlNode listIntNode = playerInfo.SelectSingleNode("listInt");
        XmlNodeList intList = listIntNode.SelectNodes("int");
        this.listInt = new List<int>();
        for (int i = 0; i < intList.Count; i++)
        {
            this.listInt.Add(int.Parse(intList[i].InnerText));
        }

        XmlNode itemList = playerInfo.SelectSingleNode("itemList");
        XmlNodeList items = itemList.SelectNodes("Item");
        this.itemList = new List<Item>();
        foreach (XmlNode item in items)
        {
            Item item2 = new Item();
            item2.id = int.Parse(item.Attributes["id"].Value);
            item2.num = int.Parse(item.Attributes["num"].Value);
            this.itemList.Add(item2);
        }

        XmlNode itemDic = playerInfo.SelectSingleNode("itemDic");
        XmlNodeList keyInt = itemDic.SelectNodes("int");
        XmlNodeList valueItem = itemDic.SelectNodes("Item");

        this.itemDic = new Dictionary<int, Item>();
        for (int i = 0; i < keyInt.Count; i++)
        {
            int key = int.Parse(keyInt[i].InnerText);
            Item value = new Item();
            value.id = int.Parse(valueItem[i].Attributes["id"].Value);
            value.num = int.Parse(valueItem[i].Attributes["num"].Value);
            this.itemDic.Add(key, value);
        }
    }
}

5、存储XML

注意:存储xml文件 在Unity中一定是使用各平台都可读可写可找到的路径
  1.Resources 可读 不可写 打包后找不到  ×
  2.Application.streamingAssetsPath 可读 PC端可写 找得到  ×
  3.Application.dataPath 打包后找不到  ×
  4.Application.persistentDataPath 可读可写找得到   √
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using UnityEngine;

public class SaveXml : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        #region 知识点一 决定存储在哪个文件夹下
      

        string path = Application.persistentDataPath + "/PlayerInfo2.xml";
        print(Application.persistentDataPath);
        #endregion

        #region 知识点二 存储xml文件
        //关键类 XmlDocument 用于创建节点 存储文件
        //关键类 XmlDeclaration 用于添加版本信息
        //关键类 XmlElement 节点类

        //存储有5步
        //1.创建文本对象
        XmlDocument xml = new XmlDocument();

        //2.添加固定版本信息
        //这一句代码 相当于就是创建<?xml version="1.0" encoding="UTF-8"?>这句内容
        XmlDeclaration xmlDec = xml.CreateXmlDeclaration("1.0", "UTF-8", "");
        //创建完成过后 要添加进入 文本对象中
        xml.AppendChild(xmlDec);

        //3.添加根节点
        XmlElement root = xml.CreateElement("Root");
        xml.AppendChild(root);

        //4.为根节点添加子节点
        //加了一个 name子节点
        XmlElement name = xml.CreateElement("name");
        name.InnerText = "唐老狮";
        root.AppendChild(name);

        XmlElement atk = xml.CreateElement("atk");
        atk.InnerText = "10";
        root.AppendChild(atk);

        XmlElement listInt = xml.CreateElement("listInt");
        for (int i = 1; i <= 3; i++)
        {
            XmlElement childNode = xml.CreateElement("int");
            childNode.InnerText = i.ToString();
            listInt.AppendChild(childNode);
        }
        root.AppendChild(listInt);

        XmlElement itemList = xml.CreateElement("itemList");
        for (int i = 1; i <= 3; i++)
        {
            XmlElement childNode = xml.CreateElement("Item");
            //添加属性
            childNode.SetAttribute("id", i.ToString());
            childNode.SetAttribute("num", (i * 10).ToString());
            itemList.AppendChild(childNode);
        }
        root.AppendChild(itemList);

        //5.保存
        xml.Save(path);
        #endregion

        #region 知识点三 修改xml文件
        //1.先判断是否存在文件
        if( File.Exists(path) )
        {
            //2.加载后 直接添加节点 移除节点即可
            XmlDocument newXml = new XmlDocument();
            newXml.Load(path);

            //修改就是在原有文件基础上 去移除 或者添加
            //移除
            XmlNode node;// = newXml.SelectSingleNode("Root").SelectSingleNode("atk");
            //这种是一种简便写法 通过/来区分父子关系
            node = newXml.SelectSingleNode("Root/atk");
            //得到自己的父节点
            XmlNode root2 = newXml.SelectSingleNode("Root");
            //移除子节点方法
            root2.RemoveChild(node);

            //添加节点
            XmlElement speed = newXml.CreateElement("moveSpeed");
            speed.InnerText = "20";
            root2.AppendChild(speed);

            //改了记得存
            newXml.Save(path);
        }

        #endregion

        #region 总结
        //1.路径选取
        //在运行过程中存储 只能往可写且能找到的文件夹存储
        //故 选择了Application.persistentDataPath

        //2.存储xml关键类
        //XmlDocument  文件  
        //   创建节点 CreateElement
        //   创建固定内容方法 CreateXmlDeclaration
        //   添加节点 AppendChild
        //   保存 Save
        //XmlDeclaration 版本
        //XmlElement 元素节点  
        //   设置属性方法SetAttribute

        //3.修改
        //RemoveChild移除节点
        //可以通过 /的形式 来表示 子节点的子节点 
        #endregion
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-12-10 11:22:49  更:2021-12-10 11:24:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 21:41:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码