То есть, что связано с чем и как перемещаться между строками речи, когда заканчивается разговор?
Если у вас есть примеры базового дерева диалогов в C #, пожалуйста, опубликуйте их.
То есть, что связано с чем и как перемещаться между строками речи, когда заканчивается разговор?
Если у вас есть примеры базового дерева диалогов в C #, пожалуйста, опубликуйте их.
Ответы:
Название «диалоговое дерево» немного вводит в заблуждение - обычно это простые ориентированные графы , а не просто деревья . Базовая структура данных таких графиков обычно состоит из неких «данных» для узлов, которые представляют точки, в которых мы находимся в разговоре, и ссылок от них на другие узлы, которые представляют то, что говорят и делают участники и при желании иметь условия для них, чтобы ограничить их видимость или сценарии для выполнения различных дополнительных действий. Обычно один из узлов является начальным узлом по умолчанию (типичными метками для этого являются «ROOT», «START» и «GREETING»), а узлы, у которых нет действительных ссылок, ведущих из них, завершают диалог.
В большинстве случаев график представляется в памяти в виде списка Node
структур данных, каждая из которых имеет по меньшей мере идентификатор и список 0..n Link
структур данных. Список может быть локальным для NPC или глобальным; второй случай предпочтителен, если у вас есть много общих NPC, с которыми можно поговорить для информации, но не предлагать никаких конкретных разговоров самостоятельно. Система сама находит начальный узел разговора для NPC, запоминает его идентификатор в качестве идентификатора текущего разговора, представляет действующие в настоящий момент ссылки для выбора игрока (или «[конец разговора]», если нет действительных ссылок) и ожидает вход. Когда игрок выбирает ссылку, отображаются соответствующие диалоговые строки и запускаются все связанные сценарии.
Вместо сложных правил и условий для ссылок вы можете вместо этого использовать простую «допустимую» логическую переменную, которую затем можно изменить либо из сценариев других диалоговых ссылок (включая сценарий по умолчанию из начального узла), либо из внешних источников. механизмы. В общем, этот подход проще, но подходит только для игр с очень небольшим количеством таких разговоров, поскольку он перемещает логику «Когда возможен этот ответ?» вдали от самих данных ответа.
Обратите внимание, что структура, которую я здесь описываю, немного отличается от структуры Byte56 тем, что узлы не должны иметь никаких строк диалога; ссылки могут иметь их все. В самом основном варианте это переводится в следующую структуру.
Деревья диалогов создаются с помощью структуры ориентированного графа .
График перемещается на основе диалоговых решений, которые принимает игрок. Параметры диалога, предоставляемые пользователю, происходят от краев, которые определяют пути к другим узлам диалога.
Ориентированные графы являются базовой структурой данных. Они могут быть легко реализованы, и вы, вероятно, захотите реализовать это самостоятельно. Так как вы захотите адаптировать график к вашим потребностям в диалоге.
Некоторые узлы могут иметь особые условия для отображения. Например, игроку потребуется навык речи выше X. Или игрок должен завершить миссию Z, прежде чем он сможет пройти вниз по одной ветви диалога. Или они должны спросить что-то 4 раза, прежде чем NPC обсудит это с ними. Эти функции будут индивидуальны для вашей игры. Но стоит упомянуть, когда вы реализуете обход узлов и ребер. Конечно, всегда лучше начинать с самой простой формы и строить ее оттуда.
Я построил простую систему диалогового дерева: http://iki.fi/sol/d3/ сам «движок» в настоящее время просто c, но данные, создаваемые редактором, довольно просты в использовании на любом языке. Инструмент выводит XML, JSON и пользовательский двоичный формат.
Основная концепция довольно проста:
Каждый узел (который я называю «карточкой», как и в приведенном выше аналоге) диалога состоит из текста вопроса и ноля или более ответов. Каждый из ответов ведет к другой карточке.
Существует также система тегов, где определенные ответы показываются пользователю, только если тег установлен (или тег не установлен). Ввод карты устанавливает (или отменяет) указанные теги.
Это почти все, что нужно для любого диалогового окна в игре. «Текст вопроса» может быть простым текстом или сценарием для управления анимацией или еще чем-то.
Вы можете использовать TreeSharp и деревья поведения для моделирования диалоговой системы. TreeSharp - это библиотека, которая обеспечивает простую реализацию дерева поведения. ИА боты для вау с этим покончено, так что уже пора ... :)
В моей реализации есть узлы, которые позволяют выбирать между ответами, и каждый ответ может быть присоединен к другому диалогу или действию, или последовательности действий, или узлу, который позволяет перейти к другому диалогу ... или что вы хотите ...
Я использовал мозговой редактор, чтобы сделать это визуально ... но в конце он производит код на C # на основе Treeharp ...
Вы хотите ориентированный (возможно, циклический) граф.
Вы бы смоделировали узлы как объекты, и все исходящие стрелки в узле графа также моделируются как отдельные объекты. Узел имеет список исходящих стрелок, и каждый объект «стрелка» имеет текст для отображения и ссылку на пункт назначения. Не уверен, но я думаю, что в C # на объекты всегда ссылаются, поэтому сначала вы просто создаете объекты, а затем, когда вы создаете объекты стрелок, вставляете один и тот же объект в поле назначения двух стрелок. (В C ++ вы бы использовали ссылку или тип указателя, Node & или Node *)
Для загрузки таких вещей с диска обычно присваивают каждому узлу уникальный идентификационный номер, а затем загружают все узлы в массив, индекс которого является этим уникальным номером. Затем стрелки сериализуются путем записи числа, а не самого объекта.
Когда вы загружаете стрелку, вы используете массив и идентификатор, чтобы получить ссылку на узел, на который она указывает. Если вы выписали объект дважды, вы получите два отдельных объекта, которые просто выглядят одинаково, что, вероятно, не то, что вы хотели.
Обработка диалогового дерева становится очень простой. Вы просто помещаете корневой узел в currentNode
переменную, как-то отображаете все это, а затем, когда выбор сделан, устанавливаете rootNode
пункт назначения стрелки. В псевдокоде:
Node& currentNode = dialogTree.node[0];
while( currentNode != END_CONVERSATION_PSEUDO_NODE )
{
stage.displayNode( currentNode );
currentNode = stage.waitForUserToChoose();
}
Недавно мне пришлось разработать что-то подобное с помощью Node, и я выбрал очень простую структуру текстового файла для представления ориентированного графа узлов разговора.
Вы можете увидеть полученный код и текстовый формат по адресу:
https://github.com/scottbw/dialoguejs
Он не поддерживает условия или триггеры событий (пока), но, вероятно, достаточно прост для начала для многих разработчиков игр.
(Сам код в GPL, кстати)
dialog-tree
тег.