用XML做的Unity NPC对话系统


本文提供全流程,中文翻译。

Chinar坚持将简单的生活方式,带给世人!

(拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例)



游戏效果:


1

Create XML Document —— 创建所需的XML文档

注意路径:

我的XML文档”Dialog.xml”放在了 Assets 目录下创建的一个 Data 目录中

如果名字不一样,需要改名

或者直接修改解析XML代码中的读取路径,为你自己的路径

document.Load(Application.dataPath + "/Data/Dialog.xml"); //加载 XML 内容

<?xml version="1.0" encoding="utf-8"?>
<!-- Dialog System ; Background ; Image ; Music -->
<root>
<bg>背景1</bg>
<bgm>雨声</bgm>
<say>
<name>船长</name>
<image>曲境一号船长1</image>
<sound>花痴诗1</sound>
<content>我的小鱼你醒了,还记认识早晨吗?</content>
</say>
<say>
<name>秀秀</name>
<image>秀秀1</image>
<sound>花痴诗2</sound>
<content>昨夜你曾经说, 愿夜幕永不开启。</content>
</say>
<say>
<name>船长</name>
<image>曲境一号船长2</image>
<sound>花痴诗3</sound>
<content>你的香腮边轻轻滑落的</content>
</say>
<say>
<name>秀秀</name>
<image>秀秀2</image>
<sound>花痴诗4</sound>
<content>是你的泪,还是我的泪?</content>
</say>
<bg>背景2</bg>
<say>
<name>秀秀</name>
<image>秀秀3</image>
<sound>花痴诗5</sound>
<content>初吻吻别的那个季节</content>
</say>
<say>
<name>船长</name>
<image>曲境一号船长3</image>
<sound>花痴诗6</sound>
<content>不是已经哭过了吗?</content>
</say>
<bg>背景3</bg>
<say>
<name>船长</name>
<image>曲境一号船长4</image>
<sound>花痴诗7</sound>
<content>我的指尖还记忆着</content>
</say>
<say>
<name>秀秀</name>
<image>秀秀4</image>
<sound>花痴诗8</sound>
<content>你慌乱的心跳</content>
</say>
<say>
<name>船长</name>
<image>曲境一号船长1</image>
<sound>花痴诗9</sound>
<content>温润的体香里</content>
</say>
<bg>背景4</bg>
<say>
<name>秀秀</name>
<image>秀秀1</image>
<sound>花痴诗10</sound>
<content>那一缕长发飘飘…</content>
</say>
</root>

2

Audio Manager —— 音频管理器脚本

将此脚本挂在保证激活状态的 GameObject 上,并添加 2 个 AudioSource 组件

通过拖动的方式

在 Inspecter 面板中将 2 个 AudioSource 组件拖到 ↓

背景音: BgmAudioSource 和音效: SeAudioSource 框中

代码直接 Copy

using UnityEngine;

/// <summary>
/// 声音管理类
/// </summary>
public class AudioManager : MonoBehaviour
{
public static AudioManager Instance; //单例
public AudioSource BgmAudioSource; //背景音
public AudioSource SeAudioSource; //音效
private AudioClip _clip; //音乐文件 /// <summary>
/// 初始化函数
/// </summary>
void Start()
{
Instance = this;
} /// <summary>
/// 播放背景音
/// </summary>
public void PlayBgm(string inName)
{
_clip = Resources.Load<AudioClip>(inName); //加载音乐文件
BgmAudioSource.clip = _clip; //更换音乐文件为Clip默认文件
BgmAudioSource.Play(); //播放音乐
} /// <summary>
/// 播放音效
/// </summary>
public void PlaySe(string inName)
{
_clip = Resources.Load<AudioClip>(inName); //加载音乐文件
SeAudioSource.PlayOneShot(_clip); //播放音效,一声就完了
} /// <summary>
/// 停止背景音
/// </summary>
public void StopBgm()
{
BgmAudioSource.Stop(); //停止播放器
}
}


3

UI Manager —— 界面交互控制

将此脚本挂在保证激活状态的 GameObject 上

通过拖动的方式

Inspecter —— 面板中:分别添加声明的 6 个对象

代码直接 Copy

using UnityEngine;
using System.Xml; //引用XML
using UnityEngine.UI; //引用UI
using System.Collections.Generic; //引用集合
using UnityEngine.SceneManagement; //引用命名空间 /// <summary>
/// 枚举指令类型
/// </summary>
public enum CommandType
{
Say, //说话
Bgm, //背景音
Bg //背景
} /// <summary>
/// 基类:指令类
/// </summary>
public class Command
{
public CommandType AllType; //定义成员变量 类型对象
} /// <summary>
/// 说话指令类:继承 指令基类
/// </summary>
public class Say : Command
{
public string Name; //名字
public string Image; //图片
public string Sound; //音乐
public string Content; //内容
} /// <summary>
/// 背景音指令类:继承 指令基类
/// </summary>
public class Bgm : Command
{
public string Name; //名字
} /// <summary>
/// 背景指令类:继承 指令基类
/// </summary>
public class Bg : Command
{
public string Name; //名字
} /// <summary>
/// 对话系统
/// </summary>
public class DialogUI : MonoBehaviour
{
public List<Command> Commands = new List<Command>(); //声明一个 List 数组 类型为:Command
private int _index = 0; //默认索引为0
public GameObject GameImage; //游戏界面
public GameObject ReloadBut; //重开按钮
public Image BgImage; //背景图
public Image HeadPortrait; //头像
public Text NameText; //名字文本
public Text ConttentText; //内容文本
private bool _isExecute = false; //是否执行命令:默认不执行 /// <summary>
/// 初始化方法
/// </summary>
void Start()
{
AnalysisXml(); //调用解析XML方法
GameObject.Find("StartGameButton").GetComponent<Button>().onClick.AddListener(StartGame); //给开始游戏按钮,添加监听事件
} /// <summary>
/// 更新函数
/// </summary>
void Update()
{
if (Input.GetMouseButtonDown(0) && _isExecute == true ||
Input.GetKeyDown(KeyCode.KeypadEnter) && _isExecute == true) //如果按下鼠标左键或者按下Enter
{
OneByOneExecuteCommand(); //执行对话命令函数
}
} /// <summary>
/// 开始游戏
/// </summary>
public void StartGame()
{
GameImage.SetActive(true); //激活游戏界面
_isExecute = true; //游戏开始:可以开始执行代码
OneByOneExecuteCommand(); //游戏页面被激活的时候,就执行一次
} /// <summary>
/// 执行对话命令函数
/// </summary>
public void OneByOneExecuteCommand()
{
if (_index >= Commands.Count) //下标越界:读完
{
ReloadBut.SetActive(true); //激活重载按钮
ReloadBut.GetComponent<Button>().onClick.AddListener(ReloadScene); //给按钮添加 重载场景 监听事件
_isExecute = false; //关闭执行命令
return;
} Command command = Commands[_index++]; //自增:取出一条命令 switch (command.AllType)
{
//如果类型是:Say 说话
case CommandType.Say:
Say say = (Say) command; //实例化 Say 对象 say
HeadPortrait.sprite = Resources.Load<Sprite>(say.Image); //更换头像
NameText.text = say.Name; //人物
ConttentText.text = say.Content; //说话内容
if (!string.IsNullOrEmpty(say.Sound)) //如果音效名不为空
{
AudioManager.Instance.PlaySe(say.Sound); //播放音效
}
break; //如果类型是:Bgm 背景音乐
case CommandType.Bgm:
Bgm bgm = (Bgm) command; //实例化 Bgm 对象 bgm
AudioManager.Instance.PlayBgm(bgm.Name); //播放背景音乐
OneByOneExecuteCommand(); //直接执行下一条
break; //如果类型是:Bg 背景
case CommandType.Bg:
Bg bg = (Bg) command; //实例化 Bg 对象 bg
BgImage.sprite = Resources.Load<Sprite>(bg.Name); //更换背景图片
OneByOneExecuteCommand(); //直接执行下一条
break;
}
} /// <summary>
/// 重载场景
/// </summary>
public void ReloadScene()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex); //重载当前场景
} /// <summary>
/// 解析XML
/// </summary>
private void AnalysisXml()
{
XmlDocument document = new XmlDocument(); //实例化一个xml文档
document.Load(Application.dataPath + "/Data/Dialog.xml"); //加载 XML 内容
XmlElement rootEle = document.LastChild as XmlElement; //根节点
foreach (XmlElement ele in rootEle.ChildNodes) //遍历根节点的所有子节点
{
if (ele.Name == "bgm") //如果元素的名字是XML文档中的节点"bgm"
{
Bgm bgm = new Bgm();
bgm.AllType = CommandType.Bgm;
bgm.Name = ele.InnerText;
Commands.Add(bgm); //添加到命令数组 Commands 中
}
else if (ele.Name == "bg")
{
Bg bg = new Bg();
bg.AllType = CommandType.Bg;
bg.Name = ele.InnerText;
Commands.Add(bg);
}
else if (ele.Name == "say")
{
Say say = new Say();
say.AllType = CommandType.Say;
say.Name = ele.ChildNodes[0].InnerText;
say.Image = ele.ChildNodes[1].InnerText;
say.Sound = ele.ChildNodes[2].InnerText;
say.Content = ele.ChildNodes[3].InnerText;
Commands.Add(say);
}
}
}
}


4

Finish —— 测试运行

直接点击运行 Or Alt+P

Chinar所作,Down下即可!

附:Chinar的GitHub工程案例


END

本博客为非营利性个人原创,除部分有明确署名的作品外,所刊登的所有作品的著作权均为本人所拥有,本人保留所有法定权利。违者必究


对于需要复制、转载、链接和传播博客文章或内容的,请及时和本博主进行联系,留言,Email: ichinar@icloud.com


对于经本博主明确授权和许可使用文章及内容的,使用时请注明文章或内容出处并注明网址

Unity 3D游戏-NPC对话系统With XML的更多相关文章

  1. Unity 3D游戏开发学习路线(方法篇)

    Unity 3D本来是由德国的一些苹果粉丝开发的一款游戏引擎,一直只能用于Mac平台,所以一直不被业外人士所知晓.但是后来也推出了2.5版,同时发布了PC版本,并将其发布方向拓展到手持移动设备.Uni ...

  2. 《Unity 3D游戏客户端基础框架》概述

    框架概述: 做了那么久的业务开发,也做了一年多的核心战斗开发,最近想着自己倒腾一套游戏框架,当然暂不涉及核心玩法类型和战斗框架,核心战斗的设计要根据具体的游戏类型而定制,这里只是一些通用的基础系统的框 ...

  3. Unity 3D 游戏上线之后的流水总结

    原地址:http://tieba.baidu.com/p/2817057297?pn=1 首先.unity 灯光烘焙 :Unity 3D FBX模型导入.选项Model 不导入资源球.Rig 不导入骨 ...

  4. Unity 3D游戏开发引擎:最火的插件推荐

    摘要:为了帮助使用Unity引擎的开发人员制作更完美的游戏.我们精心挑选了十款相关开发插件和工具.它们是:2D Toolkit.NGUI.Playmaker.EasyTouch & EasyJ ...

  5. Unity 3d游戏逆向及.NET Reflector工具使用介绍

    移动平台游戏框架主要有unity 3d和cocos 2d.我们首先得识别游戏使用的框架.识别Unity游戏Android平台的apk包可以直接解压,看是否有./assets/bin/Data/Mana ...

  6. 【Unity】1.0 第1章 Unity—3D游戏开发和虚拟现实应用开发的首选

    分类:Unity.C#.VS2015 创建日期:2016-03-23 一.简介 Unity是跨平台2D.3D游戏和虚拟现实高级应用程序的专业开发引擎,是由Unity Technologies公司研制的 ...

  7. 【Unity 3D 游戏开发】Unity3D 入门 - 工作区域介绍 与 入门示例

    一. 工作区域详解 1. Scence视图 (场景设计面板) scence视图简介 : 展示创建的游戏对象, 可以对所有的游戏对象进行 移动, 操作 和 放置; -- 示例 : 创建一个球体, 控制摄 ...

  8. Unity 3D游戏-消消乐(三消类)教程和源码

    Unity 消消乐教程和源码 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 Start Game -- ...

  9. Unity 3D游戏-见缝插针源码

    Unity见缝插针功能实现 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 Sphere Rotatio ...

随机推荐

  1. robot脚本编写规范

    一个robot脚本主要有四部分组成: ***settings*** 设置 ***keywords*** 关键词 ***variables*** 变量 ***test cases*** 测试用例 一般, ...

  2. PHP使用phpstorm进行断点调试

    1.下载xdebug模块 (https://xdebug.org/) 注意:带"ts"是线程安全的意思,"nts"的他没有标示,也就是说,如果是nts的要下载没 ...

  3. 20170711筛选OutLook主题并转发

    Sub 筛选OutLook主题并转发() On Error Resume Next Dim OutApp As Application Set OutApp = Application Dim Out ...

  4. alias和alias_method的区别:

    1.alias 是 Ruby 的一个关键字,因此使用的时候是 alias :new name :oldname,而 alias_method 是 module 类的一个方法,因此使用的时候是 alia ...

  5. layedit

    layedit.set({ uploadImage: { url: '' //接口url ,type: '' //默认post } }); //注意:layedit.set 一定要放在 build 前 ...

  6. HDU-4848 Wow! Such Conquering! (回溯+剪枝)

    Problem Description There are n Doge Planets in the Doge Space. The conqueror of Doge Space is Super ...

  7. SQL语句增加列、修改列类型、修改列、删除列

    1.增加列: alter table tableName add columnName varchar(30) 2.修改列类型: alter table tableName alter column ...

  8. MVC ——设置启动 URL

    Visual Studio 会以一种有助的尝试,根据当前正在编辑的视图,让浏览器请求一个 URL.但这是一个不稳定的特性. 为了对浏览器的请求设置一个固定的 URL,可以从 Visual Studio ...

  9. [Spring Boot] 使用多个Servlet

    当使用Spring boot的嵌入式servlet容器时,可以通过Spring bean或扫描Servlet组件的方式注册Servlet.Filter和Servlet规范的所有监听器(例如HttpSe ...

  10. spring--mvc添加用户及用户头像上传

    spring--mvc添加用户及用户头像上传 添加用户步骤: 1.用ajax获取省份信息 2.添加用户 代码:register.jsp <meta http-equiv="Conten ...