Структурированный вывод делает игровой процесс с NPC более многогранным. Структурированный вывод — это механизм, с помощью которого БЯМ, управляющая вашим NPC, возвращает созданные пользователем и заполненные БЯМ структуры для управления логикой игрового процесса.
Это позволяет персонажу на основе БЯМ выполнять более сложные действия: возвращать ответы на вопросы с вариантами ответа, определять, оправдана ли цена предмета, и многое другое.
И ответ, и структурированный вывод должны быть на английском языке.
Обзор
В этом разделе в persona_npc_behavior добавляется один структурированный вывод для вашей персоны. Структура interactions_response:
Записывает, сколько раз этот NPC взаимодействовал с игроком.
Хранит текущее отношение персоны к этому взаимодействию с игроком.
Содержит массив с историей отношения персоны ко всем взаимодействиям с игроком.
Для структурированного вывода необходимо:
Создать структуру, определяющую структурированный вывод.
Указать, как персона должна заполнять структуру структурированного вывода.
Определить событие, сигнализирующее о получении структурированного вывода, и подписаться на него.
Для одной персоны можно одновременно настроить несколько структурированных выводов и указать отдельные подписки для каждого их типа.
Поддерживаемые типы
В полях структур структурированного вывода поддерживаются следующие типы Verse:
intfloatboolenummessage
Отображение сообщений
Значения типа message скрываются при выводе в журнал или в игре, однако их можно отображать с помощью предназначенных для этого устройств, например:
billboard_devicehud_message_devicepopup_dialog_device
Требования
Добавление структурированного вывода в скрипт поведения NPC
В приведённом ниже коде структурированный вывод расширяет возможности нескольких БЯМ: тип prompt_binding_definition и функция RegisterAction() добавляют новые типы ответов на основе промптов игроков.
Привязка промпта — это структура, которая передаётся ИИ для регистрации действия, определённого в функции RegisterAction(). Вместе они сообщают БЯМ, когда и почему следует выполнить определённое действие с учётом промпта игрока.
Ниже приведён скрипт Verse с расширенной версией persona_npc_behavior в разделе persona_npc_behavior.verse. Этот код дополняет код из документации Добавление NPC в диалог, добавляя структурированный вывод.
Чтобы изменить код в существующем persona_npc_behavior, выполните следующие действия:
Убедитесь, что проект Verse открыт в VS Code:
В строке меню выберите Verse > Открыть проект в VS Code…
Когда откроется VS Code, найдите файл
persona_npc_behavior.verseв Проводнике VS Code.
Скопируйте приведённое ниже содержимое файла
persona_npc_behavior.verseи вставьте его в файл Verse своего проекта.Скомпилируйте код Verse на панели инструментов UEFN или в VS Code.
Пошаговый разбор скрипта Verse приведён в разделе Объяснение изменений в скрипте. Этот раздел начинается непосредственно с того места, на котором заканчивается разбор скрипта в разделе Добавление персоны к персонажу NPC.
persona_npc_behavior.verse
using { /Fortnite.com/AI }
using { /Fortnite.com/Devices }
using { /Fortnite.com/Playspaces }
using { /UnrealEngine.com/Conversations }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /Verse.org/Chat }
using { /Verse.org/SceneGraph }
using { /Verse.org/Simulation }
Объяснение изменений в скрипте
Структура
interactions_responseсодержит переменные, которые функции передают БЯМ. БЯМ использует переменные, чтобы оценить промпт и определить, как на него ответить.Verseinteractions_response := struct: @ai_description("Use the Number field to output the number of times you have spoken to this player.") Number:int @ai_description("Use the Feeling field to output how you are feeling about your current interaction with the player.") Feeling:messageДва разных
@ai_descriptionsсообщают БЯМ, что представляют собой переменные и почему их следует использовать при создании ответа.Verse@ai_description("Use the Number field to output the number of times you have spoken to this player.") Number:int @ai_description("Use the Feeling field to output how you are feeling about your current interaction with the player.") Feeling:messageФункция
OnInteractionsResponseуправляет логикой игрового процесса с помощью структурированного вывода. Это функция обратного вызова, которая срабатывает, когда сеанс ИИ создаёт структурированный вывод, соответствующий структуреinteractions_response. Этот обработчик регистрируется функциейRegisterActionвAddStructuredOutput(), а его параметр Response содержит данные, которыми модель заполнила структуру.VerseOnInteractionsResponse(Response:interactions_response):void = Logger.Print("Structured response received") Logger.Print("Number of Interactions: {Response.Number}") Logger.Print("Feeling: {Localize(Response.Feeling)}") # Drive gameplay logic hereФункция
AddStructuredOutputрегистрирует действие структурированного вывода NPC в его сеансе ИИ. Благодаря этому модель может передавать данные о взаимодействии обратно в игровой процесс. Этот код выполняет две задачи. Сначала создаётсяprompt_binding_definition— небольшой дескриптор сименемиописаниемдействия. Оба значения обёртываются с помощью вспомогательной функцииMakeMessage, которая преобразует строковые литералы в значения типа message. Текст описания сообщает модели, когда использовать это действие: в данном случае — каждый раз, когда игрок говорит с NPC.Затем вызывается
Session.RegisterAction, куда передаются привязка, значение true, тип структурыinteractions_responseи обработчикOnInteractionsResponse. Это указывает сеансу передавать вOnInteractionsResponseданные структурированного вывода, соответствующегоinteractions_response.RegisterActionвозвращает объект cancelable, который обёртывается вoption{}и сохраняется вInteractionsResponseSubscription, чтобы подписку можно было отменить в методеOnEnd.VerseAddStructuredOutput():void = if: NPCEntity := GetEntity[] PersonaComponent := NPCEntity.GetComponent[persona_component] Session := PersonaComponent.GetAISession() then: # Create a prompt_binding so that we can use it on RegisterAction InteractionBinding:prompt_binding_definition = prompt_binding_definition: Name := MakeMessage("InteractionBinding") Description := MakeMessage("Signals whenever the player has spoken to you.")OnBeginдобавляет структурированный вывод в сеанс и назначает игрока целью диалога. Если игроки могут присоединяться к игре после её начала, добавляйте их при возникновенииPlayerAddedEventили когда игрок подходит к NPC и активирует триггер.VerseOnBegin<override>()<suspends>:void= AddStructuredOutput() AddPlayersAsConversationTarget()В
OnEndподпискаInteractionsResponseSubscriptionочищается и удаляется у всех игроков. Это рекомендуемый подход.VerseOnEnd<override>():void= if (Subscription := InteractionsResponseSubscription?): Subscription.Cancel() for (Player : GetEntity[].GetPlayspaceForEntity[].GetPlayers()): RemovePlayerAsConversationTarget(Player)
Проверка структурированного вывода
Теперь для NPC настроен структурированный вывод. Каждый раз, когда персона говорит, подаётся сигнал interactions_response.
Проверяйте поведение персонажа на основе БЯМ, чтобы он интереснее отвечал на ваши внутриигровые промпты и реагировал на них.