利用xml做简单剧情对话框

关于XML,与JSON是最常用的两种有特定语法格式的字符串文本。(JSON我已经忘得差不多了- -过两天我再重新研究下。。。),他们可以作为网络传输,同时也可以作为本地的数据存储。是非常有用的存储数据方式。 比如他们可以作排行榜,也可以作为进度或者玩家坐标的保存等等。
上次我用sqlite简单的制作了一个排行榜,今天利用半天的时间重温了下XML,所以用XML制作了一个简单的剧情对话框。如有错误请指正。

首先,一定别忘记导入system.xml!没这个也就别做XML了。。。。
其实,XML相对于sqlite本地数据库是容易很多的,我一部分一部分说。

第一部分:创建XML

关于如何创建XML,其实就六个步骤!在之后的代码注释中我标注的很明确,在这里也写一遍。
1.初始化xml
2.创建XML中的元素
3.设置属性(也可不设置)
4.按顺序设置子元素
5.设置元素中的数值
6.保存
所以只要熟练掌握着六步,创建一个xml就很容易了 (引入system.io是为了判定路径是否存在)。

第二部分:读取XML

既然创建,那必然就要涉及读取。读取的步骤就是:

1.初始化Xml
2.读取创建好的xml文档
3.读取出要查找的子节点
4.遍历子节点
第三部分:更新xml
其实更新xml就是在读取的基础上进行更改的,在第二部分的第4个步骤中,可以取选择读取出某一条数据,也可以选择去更改某一条数据。如果不太明白,看了下面我给的代码你就明白了。不过不要忘了,更新xml最后一定要保存,否则还是更改不了的。

代码如下:

[code]csharpcode:

using UnityEngine;
using System.Collections;
using System.Xml;
using System.IO;
using UnityEngine.UI;
public class XMLmanager {

    /// <summary>
    /// 单例模式
    /// </summary>
    private static XMLmanager instance;
    public static XMLmanager Instance
    {
        get
        {
            if (instance == null )
            {
                instance = new XMLmanager ();
            }
            return instance;
        }
    }

    private XMLmanager() { }

    /// <summary>
    /// 创建XML
    /// </summary>
    /// <param name="path"></param>
    /// <param name="word1"></param>
    /// <param name="word2"></param>
    /// <param name="word3"></param>
    /// <param name="word4"></param>
    public void CreatXML(string path,string word1,string word2,string word3,string word4 )
    {
        //是否存在路径,需引用System.IO
        if (!File .Exists(path ))
        {

            //第一步:初始化xml文档
            XmlDocument doc = new XmlDocument ();

            //第二步:创建XML中的元素
            XmlElement root = doc.CreateElement( "Story");
            XmlElement text1 = doc.CreateElement( "word");
            XmlElement text2 = doc.CreateElement( "word");
            XmlElement text3 = doc.CreateElement( "word");
            XmlElement text4 = doc.CreateElement( "word");

            //第三步:设置属性(也可不设置)
            text1.SetAttribute("ID","1");
            text2.SetAttribute("ID","2");
            text3.SetAttribute("ID","3");
            text4.SetAttribute("ID","4");

            //第四步:按顺序设置子元素
            doc.AppendChild(root );
            root.AppendChild(text1 );
            root.AppendChild(text2 );
            root.AppendChild(text3 );
            root.AppendChild(text4 );

            //第五步:设置元素中的数值
            text1.InnerText = word1;
            text2.InnerText = word2;
            text3.InnerText = word3;
            text4.InnerText = word4;

            //第六步:保存
            doc.Save(path );
            Debug.Log ("Creat is success!" );
        }
    }

    /// <summary>
    /// 读取XML文档
    /// </summary>
    /// <param name="path"></param>
    public void LoadXML(string path )
    {
        if (File.Exists(path))
        {
            XmlDocument doc = new XmlDocument ();
            doc.Load(path );

            //查找story下所有子节点
            XmlNodeList nodeList = doc.SelectSingleNode("Story").ChildNodes;
            //遍历
            foreach (XmlElement list in nodeList)
            {
                //如果你想执行什么操作,可以在这里写
                Debug.Log (list.InnerText);
            }
        }
    }

    /// <summary>
    /// 更新XML内容
    /// </summary>
    /// <param name="path"></param>
    /// <param name="changeword"></param>
    public void   UpdateXML(string path,string changeword)
    {
        if (File.Exists(path))
        {
            XmlDocument doc = new XmlDocument ();
            doc.Load(path );

            XmlNodeList nodeList = doc.SelectSingleNode("Story").ChildNodes;

            foreach (XmlElement list in nodeList)
            {
                if (list.GetAttribute("ID") == "1" )
                {
                    list.InnerText = changeword;
                    Debug.Log ("haschanged my XML" );
                }
            }

            //记得保存
            doc.Save(path );
        }
     
    }
}
以上就是我利用单例写的一个xml管理脚本,这个脚本是不用挂到任何物体上的。 下面来个测试吧,测试代码如下:

[code]csharpcode:

using UnityEngine;
using System.Collections;

public class StoryMgr : MonoBehavIoUr {

             void Start () {
        string path = Application .dataPath + "/story.xml" ;
        string word1 = "会XML了吗?" ;
        string word2 = "真的会了?" ;
        string word3 = "你确定?" ;
        string word4 = "好吧你会了。" ;
        XMLmanager.Instance.CreatXML (path,word1,word2,word3,word4 );

        XMLmanager.Instance.LoadXML (path);

        string changeWord = "永不满足,不断学习,才能进步" ;
        XMLmanager.Instance.UpdateXML (path,changeWord );
            }
}
来看结果,创建后的初始数据:


更新后的数据:


现在来说如何把这几句话导出来,制作一个简单的剧情对话框(上次用的UGUI作的排行榜,这次用NGUI吧- -。。。)
首先我的制作效果是这样的,点击let's talk,弹出剧情框(再点击会关上,利用tweenScale控制),不断点击yes,按照xml这几句话的顺序输出出来,之后都读完了再点yes会关上剧情框。点击no会关上。另外又加了个剧情框背景的拖拽,以及右上黑色条条的线控制背景大小。(这次把自适应都弄了。。。)



我拿之前测试的脚本改写了下,代码如下:

[code]csharpcode:

using UnityEngine;
using System.Collections;
using System.Xml;
public class StoryMgr : MonoBehavIoUr {

    private string path;    //定义路径
    private int indexi;     //与xml属性对应值相对应

    private TweenScale _tweenScale;         //控制弹出剧情框动画
    public  UILabel _textLabel;             //显示xml文档内容的label

	void Start () {
        indexi = 0;
        _tweenScale = GameObject.Find("storyBg").GetComponent<TweenScale>();

        path = Application.dataPath + "/story.xml";
        string word1 = "会XML了吗?";
        string word2 = "真的会了?";
        string word3 = "你确定?";
        string word4 = "好吧你会了。";
        XMLmanager.Instance.CreatXML(path,word4 );
       
	}

    /// <summary>
    /// Button点击事件(Yes),读取xml文档,并将读取的数据传递给label
    /// </summary>
    public void LoadNextXMLdata()
    {
        indexi++;
        XmlDocument doc = new XmlDocument();

        doc.Load(path);

        XmlNodeList nodeList = doc.SelectSingleNode("Story").ChildNodes;

        foreach (XmlElement xe in nodeList)
        {
            if (xe.GetAttribute("ID") == indexi .ToString () && _textLabel != null )
            {
                _textLabel.text = xe.InnerText;
            }
        }
            //当indexi为5的时候就没有数据了,再点击关闭这个剧情框
        if (indexi > 4)
        {
            _tweenScale.PlayReverse();

        }
    }


    /// <summary>
    /// 打开剧情框,Button(Let's talk)
    /// </summary>
    public void OpenDialogFrame()
    {
        XmlDocument doc = new XmlDocument();

        doc.Load(path);

        XmlNodeList nodeList = doc.SelectSingleNode("Story").ChildNodes;

        foreach (XmlElement xe in nodeList)
        {
            if (xe.GetAttribute("ID") == "1")
            {
                _textLabel.text = xe.InnerText;
                indexi = 1;
            }
        }

        _tweenScale.PlayForward();
    }

    /// <summary>
    /// 关闭剧情框,Button(No)
    /// </summary>
    public void CloseDialogFrame()
    {
        _tweenScale.PlayReverse();
        indexi = 0;
        _textLabel.text = "";
    }
}

以上就是今天的内容~希望对初学者有帮助,希望大神大牛们也能给予小弟帮助~~~另外我想抱怨一下。。。我发个文章说我包含不良信息,我也找不到哪有。。害我一点一点上传,每次重新编辑加上一部分内容才行。。太坑了!

(p.s.有人问我,XmlElement 和 XmlNode 这俩有啥区别。。。一个是元素类,一个是节点类。这俩的区别就在于,节点类它不仅有属性,而且包含了他的子节点,而元素类只拥有它的属性,也就是说,其实元素类是节点类的一个子集。。。我这么说能明白否- -。。。。)

相关文章

php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念