НПС в видеоиграх: как работают неигровые персонажи (с играбельными демо)
Создайте свою игру с НПС
Что такое НПС в видеоигре? Узнайте, как устроены НПС, как они ведут себя, и поиграйте в четыре настоящие 3D-игры в браузере, где неигровые персонажи двигаются, говорят и реагируют.
НПС в видеоигре — это неигровой персонаж: сущность, которой игрок не управляет напрямую, но которая занимает место в пространстве, хранит состояние и реагирует на условия мира. Термин намеренно широк, и именно эта широта порождает большую часть путаницы. Лавочник с расписанием, напарник, который идёт за вами по коридору, и бродячий торговец, повторяющий одну и ту же реплику, — все они НПС, но устроены они по-разному и стоят в работе неодинаково.
На этой странице рассказывается, чем на самом деле является НПС, как его создают и как отличить его от скриптового триггера, который лишь выглядит живым. В качестве рабочих примеров используются четыре играбельных мира с этого сайта — Agent Sprite Forge, The Cyclops’ Island, Mini World и сам 3D-конструктор игр, — чтобы вы могли подойти к НПС и понаблюдать за его поведением, а не читать о нём.
Краткий ответ: что считается НПС в видеоигре
НПС — это любой персонаж игрового мира, которым не управляет игрок напрямую. У него есть позиция, состояние и хотя бы одно поведение, которое срабатывает без нажатия кнопки игроком. Если убрать игрока из сцены, а персонаж всё равно что-то делает — идёт по маршруту, открывает дверь, реагирует на событие рядом, — это НПС.
Разделительная линия между персонажем и механизмом — это владение состоянием. Персонаж владеет переменными, которые сохраняются между кадрами: текущим здоровьем, текущей целью, текущим индексом патрулирования, текущим узлом диалога. Механизм на практике не имеет состояния: он срабатывает один раз при выполнении условия — и на этом всё. Нажимная плита, открывающая ворота, — это механизм. Стражник, который реагирует на открытие ворот, помнит, что вы там стояли, и меняет свой маршрут, — это НПС. Разница не в визуальной детализации. Разница в том, переживает ли что-нибудь тот кадр, в котором произошло событие.
Краткая история НПС в видеоиграх
Текстовые приключения конца 1970-х и 1980-х годов использовали НПС как цели для парсера. Персонаж существовал лишь как именованное существительное, которое распознавал парсер, плюс небольшой набор флагов. Вор в ранних текстовых приключениях крал предмет, если вы находились в той же комнате и он ещё этого не делал, — это НПС с двумя переменными: присутствие и флаг «уже украл». Ни поиска пути, ни анимации, ни расписания. Поведение было во флаге, а не в персонаже.
НПС эпохи спрайтов добавили анимацию и столкновения, но само поведение осталось тонким. Горожанин ходил по фиксированному циклу из двух точек, проигрывал анимацию покоя, когда игрок оказывался в радиусе, и открывал окно диалога при контакте. Важным техническим изменением стало то, что теперь у НПС была позиция в физическом мире, а значит, он должен был быть дешёвым. Когда на экране 8- и 16-битного железа одновременно находились десятки персонажей, каждый НПС получал несколько байтов состояния и выполнял проверку на кадр не сложнее сравнения расстояний.
НПС с расписанием появились, когда бюджеты памяти и процессора позволили персонажу существовать независимо от местоположения игрока. Лавочник со значением часов работы, домашней точкой маршрута и маршрутом ходьбы может оказаться в другом месте, когда вы придёте, и это отсутствие понятно игроку. Реализация — это часы плюс таблица подстановки: в 21 игровой час цель — домашняя точка; в 08 — магазин. Игрок никогда не видит таблицу, только её следствие.
Генерируемые НПС — это нынешняя эпоха. Вместо того чтобы прописывать по реплике на каждое состояние, вы пишете описание персонажа и позволяете модели создавать диалоги, выкрики или поведение во время выполнения. Компромисс теперь не в объёме памяти, а в предсказуемости: сгенерированную реплику нельзя полностью просмотреть заранее, поэтому нужны ограничения по тону, длине и тому, на что НПС разрешено ссылаться. В 3D-конструкторе игр подсказки для НПС ограничены описанием и небольшим набором поведений именно по этой причине.
Как создают современных НПС
Каждый НПС — это набор из пяти взаимодействующих частей: состояние, навигация, анимация, диалог и восприятие. Состояние — это данные, которыми владеет НПС: здоровье, цель, индекс патрулирования, узел диалога, уровень тревоги. Навигация — это то, как он перемещается между точками. Анимация — это то, как отображаются движение и моменты покоя. Диалог — это текст и голос, порождаемые в ответ на условия. Восприятие — это вход, сообщающий НПС, что что-то изменилось: обычно проверка расстояния, луч видимости или перекрытие триггерного объёма.
В типичном проекте эти части живут в разных местах. Состояние — это скрипт или компонент на сущности НПС: в терминах Unity — MonoBehaviour, в Godot — скрипт Node, в браузерной сборке на Three.js — обычный объект, привязанный к мешу. Навигация — это либо данные путевых точек, либо навигационная сетка. Анимация — это конечный автомат с именованными клипами, такими как покой, ходьба, атака. Диалог — это файл данных, часто небольшой граф узлов или таблица с ключами по состояниям. Восприятие — это обычно форма столкновения и проверка на кадр.
Самый частый режим отказа — расхождение состояния и анимации. НПС находится в состоянии преследования, но всё ещё проигрывает клип покоя, поэтому скользит к вам, не двигая ногами. Исправление — не в дополнительной анимации, а в том, чтобы было одно место в коде, которое записывает текущее состояние, и одно место, которое читает его для выбора клипа. Когда эти два места живут в разных скриптах, получается скольжение. Когда это одна и та же функция — нет.
Второй по частоте отказ — навигация, не соответствующая уровню. Маршрут патрулирования, построенный по старой планировке, отправит НПС в стену или за край после изменения геометрии. В браузерных сборках самый дешёвый надёжный подход — хранить точки патрулирования как именованные пустые объекты и заново разрешать их при загрузке, чтобы перенос стены не осиротил маршрут.
Восприятие — это то, на чём НПС становятся дорогими. Луч на каждый НПС в каждом кадре — это нормально для нескольких персонажей и расточительно для сотен. Обычные оптимизации — общая пространственная сетка, интервал проверок и раннее отсеивание по расстоянию до запуска любого луча. Если НПС находится в 40 метрах, а радиус его восприятия равен 8, луч вообще не должен запускаться.
Где каждая часть живёт в сцене
Состояние: на самой сущности НПС. Держите его маленьким — несколько чисел и одна строка для текущего узла диалога. Если нужно больше, разделите НПС на двух персонажей.
Навигация: как список точек в мировых координатах, хранящийся рядом со сценой, а не зашитый в модель. Анимация: как именованные клипы на риге, выбираемые одним переключателем состояния. Диалог: в отдельном файле данных, чтобы авторы могли править его, не трогая код. Восприятие: как триггерный объём плюс проверка расстояния, где луч — последний шаг, а не первый.
01
Поместите модель НПС в сцену и прикрепите компонент состояния с полями для текущего состояния, цели и индекса патрулирования.
02
Добавьте три-четыре объекта путевых точек и назовите их так, чтобы маршрут пережил правки уровня.
03
Соберите конечный автомат анимации как минимум с покоем и ходьбой и управляйте им только по значению текущего состояния.
04
Добавьте триггерный объём восприятия, размер которого соответствует радиусу осведомлённости НПС.
05
Напишите диалог как небольшую таблицу с ключами по состояниям и репликой по умолчанию для несовпавших состояний.
06
Заново разрешайте путевые точки и ключи диалога при загрузке, затем проверьте, передвинув одну стену и убедившись, что патруль всё ещё работает.
Четыре играбельных мира, четыре разновидности НПС
Самый наглядный способ понять поведение НПС — встать рядом с ним и изменить то, что он видит. Каждый из этих четырёх миров на Neta Studio демонстрирует свой поведенческий шаблон. Откройте их, войдите в зону восприятия НПС, затем выйдите и посмотрите, что изменится.
Agent Sprite Forge запускает НПС, заданных коротким описанием персонажа и небольшим набором состояний. Подойдите к одному из них, и его ответ генерируется по этому описанию, оставаясь в рамках состояний, которые предоставляет мир. Интересная проверка — повторяемость: подойдите к одному и тому же НПС дважды и сравните, насколько отличается второй ответ. Эта вариативность принадлежит модели, а не миру, — конечный автомат фиксирован.
The Cyclops’ Island использует крупного НПС со схемой «преследование и поиск». Когда игрок внутри радиуса восприятия, циклоп преследует; когда игрок разрывает линию видимости, он обыскивает последнюю известную позицию, а затем возвращается на маршрут патрулирования. Именно шаг поиска заставляет воспринимать его как персонажа, а не как самонаводящуюся ракету: он действует по устаревшей информации.
Mini World размещает нескольких небольших НПС на коротких циклах с подсказками взаимодействия. Их поведение намеренно тонкое: идти, замереть, отреагировать, когда игрок в пределах метра. Ценность здесь в количестве. Вы можете наблюдать за пятью-шестью одновременно и увидеть, насколько на самом деле дёшев убедительный цикл НПС.
3D-конструктор игр — это место, где вы размещаете и настраиваете НПС напрямую. Каждый НПС получает описание, маршрут патрулирования и набор состояний. Постройте что-нибудь небольшое — одну комнату, одного НПС, один маршрут — и проверьте границы: уменьшайте радиус восприятия, пока НПС вообще вас не замечает, затем увеличивайте его, пока он не начнёт замечать вас непрерывно. Ширина полезной полосы между этими двумя крайностями и есть задача настройки, и она существует в любом движке.
Одно замечание о производительности. В браузерной сборке затраты на НПС определяются проверками восприятия и анимацией, а не геометрией. Десять НПС с лучами на каждый кадр обойдутся дороже десяти НПС с общими проверками по интервалу, даже если высокодетализированные модели как раз у тех, что проверяются по интервалу. Если сцена подтормаживает, когда НПС активны, сначала смотрите на цикл восприятия.
- Agent Sprite ForgeНПС, управляемые описанием, с ограниченными генерируемыми ответами. Используйте его, чтобы увидеть, как небольшой набор состояний плюс подсказка о персонаже дают диалог, остающийся по теме.
- The Cyclops’ IslandЕдинственный крупный НПС с состояниями преследования, поиска и возврата к патрулированию. Используйте его, чтобы изучить, как действие по устаревшей информации воспринимается как разумность.
- Mini WorldНесколько лёгких НПС на коротких циклах с подсказками по близости. Используйте его, чтобы увидеть, как мало поведения нужно, чтобы персонаж воспринимался как присутствующий.
- 3D-конструктор игрРазмещайте НПС, задавайте описания, рисуйте маршруты патрулирования и настраивайте радиусы восприятия. Используйте его, чтобы найти рабочую полосу между НПС, который вас никогда не замечает, и тем, который не перестаёт замечать.
Почему НПС продаёт поведение, а не графика
Низкодетализированный персонаж, который ходит по маршруту, останавливается у двери и оказывается в другом месте, когда вы возвращаетесь, воспринимается как живой. Высокодетализированный персонаж, который стоит на одном месте и повторяет одну реплику, воспринимается как мебель. Игрок не оценивает полигоны. Игрок строит модель того, чего хочет персонаж, и эта модель рождается из тайминга и позиции, а не из меша.
Механизм здесь — ожидания. Если персонаж утром на рынке, а ночью дома, у игрока формируется гипотеза — у этого персонажа есть распорядок, — и при втором визите гипотеза подтверждается. Это подтверждение и есть весь эффект. Оно стоит одних часов и одной таблицы подстановки. Его нельзя заменить, добавляя детали статуе, потому что статуя никогда ничего не опровергает и не подтверждает.
Вот почему НПС с расписанием из куда более старых игр до сих пор обсуждают, а визуально превосходных статичных НПС забывают. Поведение — это и есть содержание. Модель — это упаковка. Если вы создаёте что-то в браузерном редакторе и у вас ограничено время, потратьте его на переходы состояний и маршруты патрулирования раньше, чем на текстуры.
Как отличить НПС от скриптового триггера
И НПС, и триггеры реагируют на игрока, поэтому их и путают на разборах дизайна. Различие в том, сохраняется ли что-нибудь после события. Используйте приведённые ниже признаки как контрольный список, когда решаете, на что именно вы смотрите.
Эта таблица — не проверка на чистоту. Во многих играх триггер запускает поведение НПС: триггерный объём переводит стражника из патрулирования в тревогу. Это нормально и правильно. Проблема возникает, когда триггер подаётся игроку как персонаж: он срабатывает один раз, персонаж больше ни на что не реагирует, и иллюзия рушится при второй встрече.
| Признак | Это НПС | Это скриптовый триггер |
|---|---|---|
| Повторяемость | Тот же персонаж отвечает и при второй встрече | Срабатывает один раз и больше никогда |
| Состояние | Владеет переменными, переживающими кадр, — уровень тревоги, индекс патрулирования | Не имеет состояния, кроме флага «сработал/не сработал» |
| Позиция | Перемещается по миру между встречами | Остаётся там, где его разместили |
| Область реакции | Реагирует по-разному в зависимости от контекста (время суток, здоровье, расстояние) | Одинаковый ответ независимо от контекста |
| Отказ | Может застрять, потерять цель или плохо проложить путь | Не может отказать — он либо сработал, либо нет |
| Стоимость | Бюджет восприятия и анимации на каждый кадр | Пренебрежимо мала после события |
| Диалог | Выбирает реплику из набора с ключами по состояниям | Проигрывает одну фиксированную реплику |
Зайдите в мир, которому он принадлежит
Спрайт — это персонаж, которому негде стоять. Последний шаг — тот, которого не предлагает больше никто: возьмите спрайтовую таблицу, которую вы только что создали, и поместите её в мир, по которому можно ходить, — небольшой остров, планету, дождливый уголок улицы. Каждый мир на этом сайте был создан из одного письменного описания и опубликован как страница, в которую можно играть.
Вернуться к 3D-конструктору игр
Все 31 готовых 3D-мира, игры и сцены живут на одной странице — в каждую из них можно играть.