вернуться на beanet.ru вернуться к списку проектов вернуться на главную страницу сборника

Тема: Работа с NPC копилка


Ключевые слова:
Список используемых понятий, сокращений и обозначений

перейти к общему списку

В этом разделе представлены накопленные сведения об NPC, их настройках, анимации и т.п.

Примечание: Это пополняемая "копилка" сведений (не является законченной статьей).


  • Размеры NPC в единицах движка: 72х26х26 (высота, ширина, толщина).


  • Иногда необходимо установить взаимодействие NPC с игроком. Игрок всегда указывается как !player (с предшествующим восклицательным знаком).


  • Для npc_citizen необходимо снять флаги Random Head, Random Male Head и Random Female Head (т.е. задать конкретную модель npc_citizen), иначе большинство анимаций (scripted_sequence) не будут выполняться – сообщение о том, что данная scripted_sequence не найдена для npc_citizen.
    Разумеется, если необходимо использование случайных npc_citizen, придется отказаться от использования анимации через scripted_sequence.


  • Флаг Efficient – Don’t acquire enemies or avoid obstacles блокирует анимацию NPC, поэтому его не стоит включать для NPC, участвующих в скриптовых сценах.


  • Флаг Fade Corpse – установка его вызывает плавное исчезновение убитого NPC через несколько секунд (используется с целью оптимизации, чтобы не нагружать систему).


  • После смерти NPC, носящий оружие, оставляет то самое оружие рядом с собой, если не установлен флаг Don't drop weapons. Игрок может поднимать оставленное таким образом оружие как обычное, имейте это ввиду.


  • Основная энтити для управления анимацией NPC – scripted_sequence. Используется, как правило, для выполнения одного или нескольких простых действий (например, подойти к двери и сделать движение как при открытии двери). Если необходимо, чтобы NPC произнес какую-либо фразу, используйте ambient_generic с параметром Target entity, равным имени соответствующего NPC.
    Для более сложных анимаций (например, слежение взглядом за игроком во время анимации, выполнение нескольких анимаций одновременно и др.) лучше использовать специальный редактор Face Poser (входит в состав Valve SDK). В этом же редакторе задается синхронизация движения губ NPC для новых фраз (добавляемых пользователем). Созданные таким образом системы анимаций называют сценами и на карту добавляют с помощью энтити logic_choreographed_scene.

    Замечание: с помощью редактора Face Poser можно сделать любую сцену с NPC (из набора доступных анимаций и фраз), чего нельзя сказать о scripted_sequence. Здесь уже решать Вам – на первых порах удобнее и быстрее использовать scripted_sequence, а когда столкнетесь с необходимостью изучать Face Poser – привыкнете к нему и начнете все анимации добавлять посредством choreographic_scene.

    Замечание: одна из причин перехода к Face Poser – медленная реакция NPC при использовании последовательности из нескольких scripted_sequence. Дело в том, что NPC делает паузу (1-2 секунды) перед началом выполнения следующей scripted_sequence. Так что если Вам нужно проиграть несколько анимаций без пауз между ними, используйте Face Poser.


  • Для определения отношения NPC к игроку и другим NPC в большинстве случаев используется энтити ai_relationship. Ее можно располагать в любом месте на карте.
    Однако некоторые NPC игнорируют эту энтити и продолжают вести себя в соответствии с поведением по умолчанию (например, npc_citizen будет игнорировать npc_helicopter). Предположительно, это сделано для сохранения игрового баланса или за отсутствием надобности (в Half-Life 2 игрок встречается с npc_helicopter один на один, npc_gunship довольно быстро расстреливается из гранатомета). Но существует все же способ, который помогает в таких случаях. Для этого необходимо использовать управляющую команду (Output), причем неважно, из какой энтити (запуск в начале игры можно сделать через logic_auto -> OnMapSpawn). Параметры команды необходимо определить следующим образом:

    Target Entity: <имя энтити, отношение которой надо изменить («кого»)>
    Via This Input: SetRelationShip
    With a parameter override of: <имя энтити для установки отношения («к кому»)> <вид отношения> 9999

    Здесь <вид отношения> принимает одно из значений:
    D_HT – враждебное (атака)
    D_LI – дружественное (союзник, никогда не атакуется)

    9999 - приоритет отношения (наивысший)


  • Для того чтобы NPC могли нормально передвигаться по карте, необходимо расставлять энтити info_node (info_node_*) во всех возможных местах, доступных для передвижения. Для наземных NPC подойдет просто info_node – наземные узлы (ставятся прямо на поверхность), для летающих нужны info_node_air – воздушные узлы (располагаются в воздухе).
    Дополнительное условие – желательно, чтобы каждый узел был в пределах прямой видимости хотя бы с еще одним узлом (наземный с наземным, воздушный с воздушным). Здесь «прямая видимость» означает, что между узлами можно провести прямую линию, которая не будет пересекать ни один из брашей или статическую энтити.


  • Для того чтобы NPC могли правильно передвигаться по сложным брашам, используйте обычный браш, покрытый текстурой tools/toolsnpcclip, расположив его верхнюю грань примерно вдоль сложной поверхности. Этот способ помогает также ограничить доступное для NPC пространство; обычно используются вертикальные грани, покрытые tools/toolsnpcclip.


  • NPC могут подниматься (опускаться) по ступенчатым поверхностям только в том случае, когда разница уровней для каждой пары поверхностей не больше 2-кратной высоты info_node (info_node_hint). При этом рекомендуется ставить энтити info_node* на каждой ступени (поверхности).


  • По умолчанию создаваемые NPC видят на ограниченном расстоянии от себя. Для того чтобы они видели далеко, установите флаг Long visibility/shoot на закладке Flags в свойствах конкретного NPC. Учтите, что это создаст дополнительную нагрузку на систему, так что в небольших областях действия лучше оставлять флаг выключенным (с целью оптимизации).


  • Чтобы увидеть все возможные анимации для NPC, в его свойствах откройте закладку Model и, выбирая значения из списка Sequence, наблюдайте в окне 3D-вида (редактора), что происходит с этим NPC. При этом все NPC одного типа с просматриваемым будут выполнять ту же анимацию.
    Другой способ – при выборе модели (просмотр моделей открывается кнопкой Browse, доступной при выборе атрибута World Model у некоторых энтити – типа prop_physics и prop_static) откройте закладку Sequences и выделяйте значения в списке. В верхнем окне 3D-вида (просмотрщика) модель будет выполнять соответствующую анимацию.
    Третий способ – в редакторе Model Viewer (просмотрщике моделей) – используйте выбор анимации из списка на закладке Sequence, загрузив конкретную модель NPC.


  • Если Вы хотите создать в игре ситуацию наподобие прибытия Гордона Фримена в Сити-17 (полиция Альянса нейтральна к нему, но реагирует на приближение и кидание предметами), используйте энтити env_global, установив флаг Set Initial State и задав атрибут Global State to Set, равным Gordon pre-criminal. Атрибут Initial State установите равным On.


  • Чтобы NPC говорил определенную фразу и при этом синхронно шевелил губами, необходимо сначала убедиться, что для фразы построены фонемы (см. Сложные скриптовые сцены (choreographed scenes) в редакторе FacePoser), а затем использовать энтити ambient_generic, у которой задать атрибут SourceEntityName как имя этого NPC.


  • Некоторые интересные действия для NPC (например, npc_zombie, просыпающийся при приближении) уже реализованы Valve в виде т.н. полуфабрикатов (prefabs).
    Для их размещения на карте используйте Entity Tool (кнопка Enity Toolили Ctrl+E), выбрав из списка Categories значение Prefabs HL2. При этом ниже появляется список готовых полуфабрикатов (созданных Valve для Half-Life 2).
    Далее – просто выбираете нужный элемент и ставите на карту (также как и энтити). Если разгруппировать установленный таким образом на карту полуфабрикат, можно будет изменять атрибуты любой входящей в него энтити.


  • Бессмертие того или иного NPC очень легко задается с помощью энтити filter_damage_type. Значение атрибута DamageType установить на такой тип повреждения, который заведомо будет действовать на этого NPC (остальные повреждения игнорируются).
    Например, значение RADIATION позволяет NPC избегать повреждений от выстрелов, взрывов и пр., кроме действия радиации.


  • Если для NPC отсутствуют некоторые сцены-анимации, возможны нарушения работы скриптов и ИИ.
    "Потеря" сцен обычно происходит из-за отсутствия их в декларационном файле scenes.image. Подробнее см. следующий пункт.


  • Если Вы создаете мод Half-Life 2: Episode Two (т.е. на движке OrangeBox), NPC в игре перестанут разговаривать, возможны нарушения скриптов и ИИ. Причина кроется в том, любое событие, в котором NPC произносит фразу (для npc_citizen: приветствовать игрока, передать патроны, предупредить группу о появлении врагов и пр., также для других говорящих NPC), проигрывается в виде сцены (*.vcd-файла).
    Естественно, при создании мода информация об этих сценах отсутствует, поэтому в игре NPC молчат.
    1 решение: с помощью программы GCFScape достать файл scenes.image из файла episode two content.gcf и скопировать в каталог /scenes Вашего мода. Однако такой способ исключает добавление собственных сцен.
    2 решение: с помощью той же программы достать все файлы сцен из соответствующих *.gcf-файлов, скопировать в тот же каталог. Затем выполнить Rebuild scenes.image…, после чего все оригинальные файлы сцен можно удалить, оставив лишь созданные Вами дополнительно.

    Например, в файле half-life 2 content.gcf в каталоге hl2/scenes/npc находятся сцены основных фраз npc_citizen. Там есть и другие сцены, которые не обязательно включать в scenes.image. Будет достаточно папок male01, female01 и каталога hl2/scenes/Expressions. Их необходимо скопировать в каталог /scenes Вашего мода в такой же иерархии (т.е. /scenes/npc/male01 и scenes/npc/female01). Затем выполнить команду Rebuild scenes.image… в редакторе FacePoser, а в окончательной версии мода их можно удалить - все равно движок будет брать их из файла half-life 2 content.gcf.

    Замечание: если планируется сделать мод независимым от наличия Half-Life 2 у игроков, в окончательной версии файлы оригинальных сцен нужно оставить.


  • Часто бывает нужно запретить NPC произносить случайные фразы, т.е. разговаривать "не по делу" (в т.ч. реагируя на приближение игрока).
    Для этого используется управляющая команда StartScripting. При этом подконтрольный NPC принимает полускриптовое состояние - игнорирует звуки опасности, команду +USE (по умолчанию клавиша E), перестаёт говорить разные фразы в состоянии бездействия (idle speech), отвечать на такие фразы и т.п.
    Вывести NPC из полускриптового состояния можно командой StopScripting.
    Доплнительно, речью NPC можно управлять с помощью энтити ai_speechfilter.


  • Если надо направить на битву друг против друга 2 отряда, можно обойтись довольно простым скриптом: поставить энтити ai_relationship с атрибутом Start Active, равным No. Задать атрибуты Subject(s) и Target(s) как две противоборствующие стороны (например, npc_citizen и npc_metropolice, TeamCitizen_* и TeamCombine_* и т.п.). Атрибут Disposition задать Hate (чтобы сделать отряды врагами), а Reciprocal установить в Yes (чтобы отношение было взаимным). Установить флаги Notify subject of target's location и Notify target of subject's location (чтобы они узнали взаимное местоположение и отправились в атаку). Теперь в нужный момент подайте управляющую команду ApplyRelationship, чтобы начать битву.
    Если надо "натравить" NPC на игрока, укажите в качестве Target(s) значение !player, установив только один флаг - Notify subject of target's location. Атрибут Reciprocal менять не нужно (по умолчанию равен No).
    Таким образом, не придется направлять NPC в нужную сторону - они сами отыщут путь по info_node*.


  • По умолчанию aiscripted_schedule прерывается, если целевой NPC увидит противника. Это исправляется присвоением атрибуту Interruptability (энтити aiscripted_schedule) значения Death (изначально он равен General).


  • Таблица для быстрого поиска внешнего вида жителя Сити-17 - Типы и модели npc_citizen.

перейти к общему списку

Номер статьи: 13

Сборник полезной информации по созданию модификаций на движке Valve Source Engine (игры Half-Life 2, Episode One, Episode Two)