【Unity3D】对话

来源:互联网 发布:电子书设计软件 编辑:程序博客网 时间:2024/05/20 16:34

对话大概是所有游戏里面最常见的,也是最有需要的一个系统了吧?现在某剑和某情怀就靠这个都能做天。Unity3D实现对话有很多种,下面就用最简单原生的UGUI,来实现对话。当然,这个界面简陋啊,不过原理就是这样的。

程序展示如下:


真正投入使用,将那些字体改改,A和B交给美工MM换成个角色立绘,将那个背面换成当前游戏正在进行的游戏场景的立绘,或者将主摄像机换成自拍独特45度角之类的……就好了,我有独特的烂游戏圈粉吸金技巧……好了,不废话了,下面是制作过程:

一、场景布置

1、如下图所示,其实根本没什么好说,都是老生常谈的东西,主要注意锚点的布置与自适应的问题,具体可以参考《【Unity3D】UGUI自适应屏幕与锚点》(点击打开链接)。


2、之后,我们在Asset新建一个文件夹Resources,只能叫这个名字,以便发布的时候,将里面的内容无条件地自动打包并发布出去。


编写如下的dialogues.xml,需要注意这个文件一定一定要用utf-8编码保存,不然乱码,否则请改第一行的编码!别用ansi编码存个用uft-8的xml就行了!实际中,你可以自己写个类似《【C#】XML读写与dataGridView的使用》(点击打开链接)的窗体xml编辑器,交给你的文案MM,剧本MM来做这项工作。反正我没有这么多MM,有也是已经有主的……真的是悲伤故事~

<?xml version="1.0" encoding="utf-8"?><dialogues>    <dialogue>        <role>A</role>        <detail>你好!</detail>    </dialogue>    <dialogue>        <role>B</role>        <detail>你好!</detail>    </dialogue>    <dialogue>        <role>A</role>        <detail>今天我们将展示如何用Unity3D实现“对话”。</detail>    </dialogue>    <dialogue>        <role>A</role>        <detail>整个过程可能有些废……但希望大家喜欢。</detail>    </dialogue>    <dialogue>        <role>B</role>        <detail>你好好做,大家一定会喜欢的^_^!</detail>    </dialogue></dialogues>
当然这个dialogues.xml是按照一定格式的,在每个<dialogue></dialogue>节点下面都是一个角色名+对话内容。你也可以定义自己的格式,但要注意未来在脚本中自己手动修改相应的节点查询。

最后,如图所示,将这个dialogues.xml导入到Asset\Resources。


二、脚本编写

场景这就布置完了,下面新建一个空物体,赋予如下脚本Dialogues.cs:

using UnityEngine;using UnityEngine.UI;using System.Collections;using System.Xml;using System.Collections.Generic;//用到了容器类  public class Dialogues : MonoBehaviour {    //这是场景中的各个物体    private GameObject roleA;    private GameObject roleB;    private GameObject roleName;    private GameObject detail;    private List<string> dialogues_list;//存放dialogues的list    private int dialogue_index =0 ;//对话索引    private int dialogue_count = 0;//对话数量    private string role;//当前在说话的角色    private string role_detail;//当前在说话的内容。void Start () {        //变量初始化        roleA = GameObject.Find("Canvas/roleA");        roleB = GameObject.Find("Canvas/roleB");        roleName = GameObject.Find("Canvas/Image/roleName");        detail = GameObject.Find("Canvas/Image/detail");        roleA.SetActive(false);        roleB.SetActive(false);        XmlDocument xmlDocument = new XmlDocument();//新建一个XML“编辑器”          dialogues_list = new List<string>();//初始化存放dialogues的list        //载入资源文件        string data = Resources.Load("dialogues").ToString();//注意这里没有后缀名xml。你可以看看编辑器中,也是不带后缀的。因此不要有个同名的其它格式文件注意!        //如果Resources下又有目录那就:Resources.Load("xx\\xx\\dialogues").ToString()        xmlDocument.LoadXml(data);//载入这个xml          XmlNodeList xmlNodeList = xmlDocument.SelectSingleNode("dialogues").ChildNodes;//选择<dialogues>为根结点并得到旗下所有子节点          foreach (XmlNode xmlNode in xmlNodeList)//遍历<dialogues>下的所有节点<dialogue>压入List        {            XmlElement xmlElement = (XmlElement)xmlNode;//对于任何一个元素,其实就是每一个<dialogue>              dialogues_list.Add(xmlElement.ChildNodes.Item(0).InnerText + "," + xmlElement.ChildNodes.Item(1).InnerText);            //将角色名和对话内容存入这个list,中间存个逗号一会儿容易分割        }        dialogue_count = dialogues_list.Count;//获取到底有多少条对话        dialogues_handle(0);//载入第一条对话的场景}void Update () {        if (Input.GetMouseButtonDown(0))//如果点击了鼠标左键        {            dialogue_index++;//对话跳到一下个            if (dialogue_index < dialogue_count)//如果对话还没有完            {                dialogues_handle(dialogue_index);//那就载入下一条对话            }            else { //对话完了                //进入下一游戏场景之类的            }        }  }    /*处理每一条对话的函数,就是将dialogues_list每一条对话弄到场景*/    private void dialogues_handle(int dialogue_index) {        //切割数组        string[] role_detail_array = dialogues_list[dialogue_index].Split(',');//list中每一个对话格式就是“角色名,对话”        role = role_detail_array[0];        role_detail = role_detail_array[1];        switch (role)//根据角色名        {   //显示当前说话的角色            case "A":                roleA.SetActive(true);                roleB.SetActive(false);                roleName.GetComponent<Text>().text = "A:";                break;            case "B":                roleB.SetActive(true);                roleA.SetActive(false);                roleName.GetComponent<Text>().text = "B:";                break;        }        detail.GetComponent<Text>().text = role_detail;//并加载当前的对话    }}
其实整个过程就是将dialogues.xml搬到Unity3D里面来,由于我们要等待用户点击鼠标才能加载一下条对话,所以先弄一个List容器将对话存着,然后点击一个,对一个序列的对话。至于C#怎么处理xml,在《【C#】XML读写与dataGridView的使用》(点击打开链接)说过了,这里不再赘述了,这部分其实和Unity3D无关,纯粹是C#的内容来的。如果你的Unity3D是用javascript写的,可以考虑下如果用javascript来处理json的方式,对话不要用xml这种方式存了,再大不了,实在不会写,c#和javascript脚本混用,管他了,请你的项目经理喝个酒就好,呵呵!

画了个渣图,表示上面的思想,简直是灵魂画师啊!大家将就看吧~


1 0