对话框树如何工作?


20

也就是说,当子对话结束时,什么与语音之间的联系以及如何在语音之间移动?

如果您有C#中基本对话框树的任何示例,请发布它们。


我认为拥有dialog-tree标签会很棒。
user1306322 2012年

询问代码示例通常不会受到青睐。
MichaelHouse

如果有一些值得共享的对话框树101代码示例,那不会有什么坏处。
user1306322 2012年

问题在于该站点是要获得正确答案的问题。它不是用于收集代码样本的。
MichaelHouse

这就是为什么句子以“ if”开头的原因。但是我要问的是有关对话框行如何以一种可以有效地转换为代码的方式相互连接的解释。毕竟,我将用C#编写它。
user1306322 2012年

Answers:


24

“对话树”这个名称有点误导-它们通常是简单的有向图,而不仅仅是。这些图的基本数据结构通常由节点的某种“数据”组成,这些数据表示我们在对话中所指向的点,并从它们到其他节点的链接表示代表参与者正在说和做的事情并有条件地限制它们的可见性或脚本来执行各种其他操作。通常,节点之一是默认的起始节点(其典型标签为“ ROOT”,“ START”和“ GREETING”),并且没有有效的链接从其引出的节点结束对话。

在大多数情况下,图形在内存中表示为Node数据结构列表,每个结构至少具有一个ID和一个0..n Link数据结构列表。该列表可以是NPC本地的,也可以是全局的。如果您有很多可以与之交谈的通用NPC,但它们自己不提供特定的对话,则首选第二种情况。系统本身会找到NPC的起始对话节点,将其ID记住为当前对话ID,为玩家提供当前有效的链接以供玩家选择(如果没有有效的链接,则为“ [结束对话]”),然后等待输入。当玩家选择一个链接时,将显示关联的对话行并运行任何关联的脚本。

您不必在链接上具有复杂的规则和条件,而可以通过简单的“有效”布尔变量来获得,然后可以从其他对话链接的脚本(包括起始节点的默认变量)或外部变量中进​​行更改。机制。通常,这种方法比较简单,但仅适用于很少进行此类对话的游戏,因为它改变了“何时可以响应?”的逻辑。远离响应数据本身。


注意,我在这里描述的结构与Byte56的结构略有不同,因为节点不需要任何对话行。链接可以包含所有内容。在最基本的变体中,这转化为以下结构。

enter image description here


+1要提到链接上的规则和条件,简单的有向图通常是不够的,当您开始需要这些条件时,事情可能会变得复杂。
Laurent Couvidou 2012年

+1我更喜欢这种结构。不过,我不建议您将其作为第一阶段。我将从更简单的事情开始。当然,这是一个更好的目标。
MichaelHouse

+1以获得非常详细的答案。稍后这对我可能会派上用场。
马顿2012年

该图像对我很有帮助,但我想知道为什么DialogueLine与Link分开?每个链接都没有自己的响应文本吗?全国人大的文本会去哪儿?在节点中拥有它没有意义吗?
凯尔·巴兰

@Danjen在此结构中,一个链接可以具有多个DialogueLine,可能来自不同的字符,直到出现下一个对话选项。这也是NPC文本所在的位置。当这些行重复时,不同的链接可以共享DialogueLines,可能在它们的列表(向量)中对其进行重新排序,用不同的行替换它们的一部分,添加感叹词等等。
马丁·索卡

16

对话框树是用有向图结构创建的。

在此处输入图片说明

根据玩家做出的对话决定遍历该图。提供给用户的对话框选项来自定义其他对话框节点路径的边缘。

有向图是一种基本的数据结构。它们很容易实现,您可能会想自己实现。因为您要根据对话框的需要定制图形。

为了显示某些节点​​,可能需要满足特殊条件。例如,玩家需要在X之上的语音技巧。或者玩家需要先完成任务Z,然后才能继续进行对话的一个分支。或者他们需要问四遍,NPC才会与他们讨论。这些功能将根据您的游戏定制。但是值得一提的是,当您实现节点和边缘遍历时。当然,最好总是从最简单的形式开始并从那里开始。


我只是不知道在这张照片中如何处理“牛顿故障”。就像如何在代码中设置这些行的顺序而不重复它们。
user1306322 2012年

您经常会发现对话框可以重复。通常,它只是以某种方式进行标记,因此用户知道他们已经选择了该对话框路径。您可以在边缘放置一个标志,以指示是否已被选中。因此,您可以允许用户再次选择它(刷新自己)还是不显示它。
MichaelHouse

1
通常不会通过代码行的排序来完成,而是通过数据结构中的引用来完成。
Kylotan

7

我建立了一个简单的dialogtree系统: http “引擎”本身目前是纯c语言,但是编辑器生成的数据使用任何语言都非常简单。该工具输出XML,JSON和自定义二进制格式。

主要概念非常简单:

您在曲折的小段落迷宫中,都一样

对话框的每个节点(与上面的类似物一样,我称之为“卡”)由问题文本和零个或多个答案组成。每个答案都会导致另一张卡片。

还有一个标签系统,仅当设置了标签(或未设置标签)时,才会向用户显示某些答案。输入卡可设置(或取消设置)指定的标签。

这几乎是游戏中任何形式的对话所需要做的一切。“问题文本”可以是纯文本,也可以是驱动动画的脚本或其他。


4

您可以使用TreeSharp和行为树为对话系统建模。TreeSharp是一个提供简单行为树实现的库。哇的IA机器人已经完成了,所以很成熟... :)

我的实现中有可以在答案之间进行选择的节点,每个答案都可以加入对话或某个动作或一系列动作,或者可以进入另一个对话框的节点……或您想要的东西。

我已经使用Brainiac编辑器进行了可视化处理...但是最后,它会基于treesharp生成c#代码。

http://www.youtube.com/watch?v=6uGg6bUYyUU


2

您需要一个有向图(可能是循环图)。

您可以将节点建模为对象,并且图形节点中的所有向外箭头也将建模为单独的对象。该节点有一个向外箭头的列表,每个“箭头”对象都有一个要显示的文本和对目标的引用。不确定,但是我认为在C#中总是引用对象,因此您只需先创建对象,然后在创建箭头对象时,将同一对象插入两个箭头的目标字段中。(在C ++中,您将使用引用或指针类型,即Node&或Node *)

为了从磁盘加载类似的东西,通常给每个节点一个唯一的ID号,然后将所有节点加载到一个数组中,其中索引就是该唯一号。然后,通过写数字而不是实际对象将箭头序列化。

加载箭头时,可以使用数组和ID来获取对其指向的节点的引用。如果您两次写出对象,则会得到两个看起来完全相同的独立对象,这可能不是您想要的。

处理对话框树变得非常简单。您只需将根节点放在currentNode变量中,以某种方式显示整个内容,然后在做出选择时将其设置rootNode为箭头的目的地。用伪代码:

Node&    currentNode = dialogTree.node[0];
while( currentNode != END_CONVERSATION_PSEUDO_NODE )
{
    stage.displayNode( currentNode );
    currentNode = stage.waitForUserToChoose();
}

1

我最近不得不使用Node开发类似的东西,并选择了一个非常基本的文本文件结构来表示对话节点的有向图。

您可以在以下位置查看生成的代码和文本格式:

https://github.com/scottbw/dialoguejs

它不支持条件或事件触发器(尚未),但对于许多游戏开发者来说可能足够简单。

(代码本身在GPL中,顺便说一句)


问题要求使用C#。
塞斯·巴丁

多哈-对不起。
Scott Wilson
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.