【Unity实战教程】unity用xml存档和读档玩家属性

前言

  1. 本内容为本人原创提供
  2. 本内特为学习者提供原创完整的工程源码下载,可参考学习或其他用途。
  3. 本内容从角色相关属性出发,对数据存取操作,一步一步推进,能直观感受。
  4. 如果后续有其他的存取游戏数据的方式,将继续提供给大家借鉴参考,希望能协助大家完成自己项目。

目录

前言

一、什么是xml

二、xml全认识

三、unity实战

1、c#对xml操作的起始工作

        1.1、玩家属性:

        1.2、C#引用:

        1.3、文件路径

2、创建xml文件

        2.1、检测文件

        2.2、创建一个xml文件

        2.3、创建根元素

        2.4、保存的xml数据

3、保存文件

        3.1、路径读取和获取节点

        3.2、声明游戏管理类

        3.3、玩家属性保存

4、读取文件

        3.1、按路径获取文件

        3.2、读取根元素并赋值

        3.3、读取背包

5、删除文件

 四、其他xml数据处理方式

 五、运行图示

 六、总结

写着写着就这么多了,可能不是特别全,不介意费时就看看吧。有时间还会接着更新。

七、工程下载地址 


一、什么是xml

        XML是扩展标记语言,也是一种与HTML非常相似的标记语言,被设计用于存储和传输数据,XML 1.0正式版于1998年发布。

        XML使用一个简单而又灵活的标准格式,为基于Web的应用提供了一个描述数据和交换数据的有效手段,当然也能作为本地数据交换的一种方法。用于软件/框架的配置文件,保存和传输数据。


二、xml全认识

1、xml第一行都是固定的文档声明,1.0版本是W3C组织于2000年发布的xml10规范。

2、encoding是整个文档的编码方式,这里我们不用去动它。

        例如:

<?xml version="1.0" encoding="utf-8"?>

3、xml 只能有一个根标签,文章或英或中都可以,跟标签有开头也必须有结束,处于闭合状态。

        例如:

<root>
    <player> </player>
    <玩家> </玩家>
</root>

        注意:<root>为根标签,</root>是闭合状态。

4、标签内部和下一级中可以插入内容。

        比如:第一种

<game>
    <player id="10005">
        <类型>战士</类型>
        <HP>200</HP>
    </player>
</game>

         第二种,也可以这样写:

<game>
    <player 类型="战士" HP="00">10005</player>
</game>

        元素的值必须用 “ ” 框住。

        两种方式根据自己喜好或者对解析方式的熟练程度。本文采用第一种方式。

4、xml标签命名有约束:

  •   不能有空格。
  •   不能有冒号。
  •   不能以数字和下划线开头(特别注意这一点)。
  •   若是英文,开头和结束大小写必须一致。

5、xml可以使用一些特殊符号

        例如:

<            &lt;
>            &gt;
&            &amp;
"            &quot;
'            &apos;

        如果xml元素中只有字符 < 或者 & ,这是非法的。会被认为是标签头,& 会被误认为是实体。

        简而言之,标签外谨慎使用。

6、DTD约束

        主要规范xml文档,DTD顺序排序安装约束我们编写xml,这里了解一下即可。

<game>
    <player id="10005">
        <类型>战士</类型>
        <HP>200</HP>
    </player>
</game>
<!Element 类型 (#PCDATA)>
<!Element HP (#PCDATA)>

        最后注意文档不要弄错格式哟,xml保存的文件后缀以 xxx.xml 结尾。当然,也只能读取xml后缀文件。


三、unity实战

        本次实战采用玩家属性单元展开,对玩家的属性进行存档和读档操作。

1、c#对xml操作的起始工作

        1.1、玩家属性:

        首先,把玩家内容属性规范好,可以创建玩家结构体,或者类。如果数据多,并且比较复杂,可以选择类,我这里选择创建一个玩家类:

public class Player
{
    public int role_id { get; set; }
    public string role_name { get; set; }
    public int role_hp { get; set; }
    public int role_mp { get; set; }
    public int role_atc { get; set; }
    public int role_def { get; set; }
    public Dictionary<string,int> role_bag { get; set; }
}
        1.2、C#引用:

        c#解析xml需要引用:

using System.Xml;

        unity对File文件进行操作,需要引用:

using UnityEngine.Windows;
        1.3、文件路径

        文件路径设置

private string xmlPath = Application.dataPath + "/Save/gamexml.xml";

2、创建xml文件

        创建一个xml文件,如果你喜欢手写xml可以选择手写xml,这里用c#方法创建xml文件:

        2.1、检测文件
    public bool IsHaveXmlDoc()
    {
        //检测文件是否存在在xmlpath路径中
        return File.Exists(xmlPath);
    }
        2.2、创建一个xml文件
        XmlDocument myxmlDoc = new XmlDocument();
        // 创建Xml declaration
        XmlDeclaration xmlDeclaration = 
            myxmlDoc.CreateXmlDeclaration("1.0", "UTF-8", null);
        myxmlDoc.AppendChild(xmlDeclaration);
        2.3、创建根元素

        xml文件中创建一个根元素

 // 根元素
 XmlElement rootElement = myxmlDoc.CreateElement("Roles");
 myxmlDoc.AppendChild(rootElement);

        根元素下创建玩家属性元素

     // Player元素
     XmlElement playerElement = myxmlDoc.CreateElement("Player");

        将元素添加到刚才创建的player元素中

// 添加子元素到Player元素  Name Hp MP .....
XmlElement childElement = myxmlDoc.CreateElement("Name");
childElement.InnerText = "主角";
playerElement.AppendChild(childElement);
childElement = myxmlDoc.CreateElement("Hp");
childElement.InnerText = "1000";
playerElement.AppendChild(childElement);
childElement = myxmlDoc.CreateElement("MP");
childElement.InnerText = "20";
playerElement.AppendChild(childElement);
childElement = myxmlDoc.CreateElement("atc");
childElement.InnerText = "5";
playerElement.AppendChild(childElement);
childElement = myxmlDoc.CreateElement("def");
childElement.InnerText = "3";
playerElement.AppendChild(childElement);

childElement = myxmlDoc.CreateElement("bag");
// (num,num)(id和数量)
childElement.InnerText = "(00003,2)|((00007,8)|((00017,99)|((00011,2)|((00006,18)";
playerElement.AppendChild(childElement);

rootElement.AppendChild(playerElement);

        注意:如果CreateElement是根开头,在xml中可以表示为:<root>。

        那么 AppendChild方法是根结束,可以表示为</root>。

        最后是保存xml文件

  myxmlDoc.Save(xmlPath);
        2.4、保存的xml数据
<?xml version="1.0" encoding="UTF-8"?>
<Roles>
  <Player>
    <Name>主角</Name>
    <Hp>40</Hp>
    <MP>65</MP>
    <atc>12</atc>
    <def>76</def>
    <bag>(00003,2)|(00007,8)|(00017,99)|(00011,2)|(00006,18)</bag>
  </Player>
  <Enemy01>
    <Name>豆豆怪</Name>
    <Hp>100</Hp>
    <MP>0</MP>
    <atc>2</atc>
    <def>1</def>
  </Enemy01>
</Roles>

3、保存文件

        保存文件与创建文件有极大相似,所以尽量简短内容

        3.1、路径读取和获取节点

        读取路径中的xml文件

        XmlDocument myxml = new XmlDocument();
        myxml.Load(xmlPath);

        获取“Roles”根节点中的元素

  XmlNodeList list = myxml.GetElementsByTagName("Roles");
        3.2、声明游戏管理类

        实现一个游戏属性管理类,并单例它,同时声明 myPlayer 方便管理我们的玩家属性

public class Gamemanager : MonoBehaviour
{
    public Player myPlayer;
    private static Gamemanager _instance;
    public static Gamemanager Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new Gamemanager();
            }
            return _instance;
        }

    }
}
        3.3、玩家属性保存

        回到xml管理类,将玩家属性赋予节点元素的InnerText

     XmlNode nd = node.ChildNodes[0];
     // 角色赋值给InnerText存数据
     nd.ChildNodes[0].InnerText = Gamemanager.Instance.myPlayer.role_name;
     nd.ChildNodes[1].InnerText = Gamemanager.Instance.myPlayer.role_hp.ToString();
     nd.ChildNodes[2].InnerText = Gamemanager.Instance.myPlayer.role_mp.ToString();
     nd.ChildNodes[3].InnerText = Gamemanager.Instance.myPlayer.role_atc.ToString();
     nd.ChildNodes[4].InnerText = Gamemanager.Instance.myPlayer.role_def.ToString();
     int i = 0;
     //将玩家的字典属性赋值给InnerText
     nd.ChildNodes[5].InnerText = string.Empty;// 初始化
     foreach (var item in Gamemanager.Instance.myPlayer.role_bag)
     {
         string str = i == (Gamemanager.Instance.myPlayer.role_bag.Count - 1) ? string.Empty : "|";
         nd.ChildNodes[5].InnerText += "(" + item.Key + "," + item.Value + ")" + str;
         i++;
     }

        记得保存文件

     myxml.Save(xmlPath);   

4、读取文件
        3.1、按路径获取文件
     // 按路径读取的xml文档
     XmlDocument myxml = new XmlDocument();
     myxml.Load(xmlPath);
        3.2、读取根元素并赋值

        读取指定的节点,获得元素节点集合

     XmlNodeList list = myxml.GetElementsByTagName("Roles");

         赋值给玩家

        //获取节点
        XmlNode node = list[0];
        if (node.ChildNodes[0].Name == "Player")
        {
            XmlNode nd = node.ChildNodes[0];
            //将节点内的集合值,InnerText 给角色赋值
            Gamemanager.Instance.myPlayer = new Player()
            {
                role_id = 0,
                role_name = nd.ChildNodes[0].InnerText.ToString(),
                role_hp = int.Parse(nd.ChildNodes[1].InnerText.ToString()),
                role_mp = int.Parse(nd.ChildNodes[2].InnerText.ToString()),
                role_atc = int.Parse(nd.ChildNodes[3].InnerText.ToString()),
                role_def = int.Parse(nd.ChildNodes[4].InnerText.ToString()),
                role_bag = ReadBag(nd.ChildNodes[5].InnerText.ToString()),
            };
        }
        3.3、读取背包

        背包是Dictionary<string,int>类型,存有编号和物品的 int 数量,用 () 归组,以 | 线分开。

读取它们时候,我们要解析上面符号,如下:

    private Dictionary<string,int> ReadBag(string str)
    {
        Dictionary<string, int> dic = new Dictionary<string, int>();  
        string[] tarry = str.Split('|');
        string s = string.Empty;
        for (int i = 0; i < tarry.Length; i++)
        {
            s = tarry[i].Replace("(", "").Replace(")","");
            string[] t = s.Split(",");
            dic.Add(t[0], int.Parse(t[1]));
        }
        return dic;
    }

        结果返回 Dictionary 


5、删除文件

        按路径删除xml文件

    public void DeleteXmlDoc()
    {
        if (IsHaveXmlDoc())
            File.Delete(xmlPath);
    }

 四、其他xml数据处理方式

    //读取节点集合
    public XmlNodeList ReadXmlNodeList(XmlDocument myxml, string str)
    { 
        return myxml.GetElementsByTagName(str);
    }
    //获取XmlNode
    public XmlNode ReadXmlNode(XmlNodeList nodelist, int index, string name)
    {
        return nodelist[index].Name.Equals(name) ? null : nodelist[0];
    }
    //读取某个元素的InnerText值
    public string ReadSingleInnerText(XmlNode node, int index)
    {
        return node.ChildNodes[index].InnerText;
    }

 五、运行图示


 六、总结

  •    不要创建过多的子节点,避免出现大量多层嵌套,让xml数据看上去非常复杂。
  •    可以创建分别玩家.xml技能.xml,将他们分开;也可以将各种系统属性统一到一个xml中。
  •    数据可以直接从xml中全部读取,也可以根据条件读取某条数据,根据实际情况使用。
  •    玩家属性数据需创建一个独立类,作为游戏实体与数据之间的中介,保证数据的独立性。
写着写着就这么多了,可能不是特别全,不介意费时就看看吧。有时间还会接着更新。

七、工程下载地址 

【unity实战案例】xml存取工程下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学与用

原创作者,在线要饭

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值