Интерактивный NPC на Unreal Engine
В настоящее время у многих на слуху использование нейронных сетей в игровой индустрии (в том числе генерация музыки, изображений, 3D моделей).
Одним из возможных применений нейронных сетей в игровой индустрии является создание «интерактивных» NPC, с которыми игрок может взаимодействовать при помощи голоса.
Ряд именитых компаний уже экспериментируют в этой области. Так, NVidia представила NVidia ACE, а Ubisoft — Neo NPC.
Есть ряд решений и от менее известных компаний: раз, два.
Признаться, меня результат не сильно впечатлил и я подумал, что, как минимум, смогу его повторить =]. Получилось или нет — решать вам.
Я решил провести небольшой RnD и подготовить «Proof of Concept»- приложение для демонстрации возможностей применения нейронных сетей для создания «интерактивных» NPC в играх.
Видео с результатами вы можете найти под катом.
Там же ссылка на демо приложение и инструкцию.
Приложение не требует сетевого соединения с другими сервисами.
Результат.
Interactive_NPC_Demo
Инструкция
Демо приложение тестировали на ноутбуке со следующими характеристиками:
AMD Ryzen 7 5800H
16Gb DDR4–3200
RTX3080 Laptop
Концепция
Игрок задает вопрос NPC голосом, NPC формулирует ответную реплику и голосом же отвечает.
У NPC должна быть своя предыстория, и он должен определенным образом реагировать на игрока.
Взаимодействие игрока с NPC должно максимально напоминать диалог с настоящим человеком. Т.е. не должно быть никаких заранее подготовленных реплик, взаимодействие должно осуществляется только голосом и, вдобавок к этому, неплохо было бы наблюдать мимику собеседника или, хотя бы, движение губ.
Кроме того, хотелось бы, чтобы NPC помнил игрока, чтобы при начале новой игровой сессии не приходилось начинать общение с самого начала.
Исходя из вышесказанного, наш «интерактивный» NPC должен выполнять следующие функции:
Слушать — преобразовывать речь игрока в текст;
Понимать — анализировать запрос игрока и формировать ответ в рамках своей предыстории\бэкграунда;
Отвечать — преобразовывать текст ответа в аудио файл и синхронизировать аудио с движением губ 3D модели;
Помнить — хранить историю общения с игроком.
Сторонние сервисы (ChatGPT, Google Speech и т.п.) использовать не будем — сегодня сервис доступен, а завтра нет (токены инвалидируются, санкции вводятся и т.п.). Плавали, знаем.
Вместо этого подберем готовые open source решения и адаптируем их под нашу задачу.
Реализация
В качестве игрового движка был выбран Unreal Engine 5.3.
Одной из причин данного выбора является возможность «из коробки» использовать высоко детализированные модели людей с готовым набором поз и анимаций — MetaHuman.
Функционал разбит на несколько плагинов:
SpeechRecognitionSystem — распознавание голоса. В основе лежит библиотека vosk.api.
UGpt — генерация ответа на текстовый запрос игрока. Используемая LLM модель — Mistral (7b). В качестве инференса модели используется llama.cpp (CPU).
SpeechGenerationSystem — преобразование текста в аудио. Плагин основан на библиотеке piper
LipSyncSystem — синхронизация анимации движения губ с аудио. Плагин представляет собой переработанную версию плагина Oculus LipSync. Оригинальный плагин не совместим с UE5 и не работает (почти) в режиме реального времени.
При написании плагинов возникла уйма нюансов, но их разбор тянет на отдельную статью…
Как это работает (в общих чертах)
Все плагины работают по единому принципу:
— при инициализации компонента плагина создается отдельный поток (FRunnableThread для FRunnable объекта) с бесконечным циклом, в котором компонент ожидает задачу на выполнение;
— компонент принимает запрос и складывает его в очередь запросов;
— на очередной итерации цикла запрос извлекается из очереди и обрабатывается;
— результат выполнения запроса складывается в очередь с результатами.
Под катом, для наглядности, приведены blueprint«ы в упрощённом виде для каждого компонента системы и ссылки на документацию к плагинам.
Blueprints
SpeechRecognitionSystem (Doc)
UGpt (Doc)
SpeechGenerationSystem (Doc), LipSyncSystem
Отдельно хотелось бы коснуться такой функции, как настройка предыстории (поведения) «интерактивного» NPC.
Для того, чтобы «прописать персонажа» необходимо прибегнуть к prompt-инжинирингу.
Для примера я решил смоделировать диалог Довакина и ярла Ульфрика из, откуда бы вы думали, игры Skyrim и подготовил вот такой простенький prompt.
Imagine that you are one of the jarls of Skyrim.
You are talking to the great warrior {USER}.
{AI} answers politely and is willing to answer any questions.
{AI} has a job for the hero.
{USER}:
-------------
USER: Dovakin
AI: Ulfric
Результат вы можете посмотреть под катом.
Диалог. Dovakin — Ulfric
Dovakin: Greetings respected Jarl.
Ulfric: Greetings mighty Dovakin, what brings you to my hall?
Dovakin: Is there any work for me? I’m a good fencer.
Ulfric: Indeed, your reputation precedes you.
Ulfric: But I have a task for someone with your skills.
Ulfric: The Stormcloaks have taken over Fort Sungard, and we need it back.
Ulfric: They’ve been using it as a base to launch attacks against our people.
Ulfric: Can you help us retake it?
Dovakin: What should I do?
Ulfric: Gather some allies and head to Fort Sungard.
Ulfric: The Stormcloaks are led by a high-ranking officer named Captain Arvel.
Ulfric: He’s a formidable opponent, but with your skills and the help of your allies, you should be able to defeat him and retake the fort.
Dovakin: What will I get for completing the task?
Ulfric: Our gratitude and the knowledge that you have helped protect the people of Skyrim.
Ulfric: And if you prove yourself to be a valuable ally, perhaps there will be other opportunities for you in the future.
Dovakin: Where should I look for them?
Ulfric: You can find potential allies among the local militia or among the other jarls.
Ulfric: Some may join you out of loyalty or for rewards.
Ulfric: Be cautious, however, as not all will be trustworthy.
Ulfric: Use your judgment wisely.
Dovakin: Where can I get supplies for this mission?
Ulfric: You can acquire supplies from various merchants or by scavenging abandoned structures.
Ulfric: Remember, preparation is key to success on the battlefield.
Dovakin: Good. I am ready to complete this mission.
Ulfric: Excellent.
Ulfric: May the gods go with you, Dovakin.
Страшно представить, что будет, если целенаправленно обучить LLM модель используя весь лор Warhammer 40000 и попросить заняться prompt инжинирингом ярого фаната вселенной…
Что дальше
научимся автоматически (ну почти) создавать двойника в MetaHuman по фотографии лица используя 3D face mesh reconstruction;
освоим voice-cloning;
постараемся еще больше «оживить» нашего NPC, добавив функцию sentiment analysis как для запросов игрока, так и для ответов NPC. Как результат — будет меняться мимика и «поведение» нашего «интерактивного» NPC;
улучшим функцию lipsync — попробуем сделать анимацию губ более плавной и «точной».
Задача максимум — создать подобие цифрового двойника человека, который будет визуально, голосом и поведением напоминать оригинал.
Заключение
Лично мне видится, что у «интерактивных» NPC есть будущее в игровой индустрии. Это будущее наступит не сегодня и не завтра, но оно наступит. Уже сейчас можно экспериментировать в попытке создать новый жанр, геймплей и т.п.
Сложно себе представить, как это скажется на работе гейм дизайнеров, сценаристов да и на индустрии в целом.
А что думаете вы? Делитесь своими соображениями в комментариях.