HUD Анимации - ixray-team/ixray-1.6-stcop GitHub Wiki
Обзор
[!IMPORTANT] Статус: Поддерживается Минимальная версия: 1.3
Система проигрывания анимаций от первого лица.
Использование предметов
Пример использования. Найдите секцию предмета, которому требуется добавить аниматор, в секцию предмета необходимо добавить строку animator_sect
, через знак равно пишется название секции худ аниматора. Например: animator_sect = conserva_eat_animator
.
Использование налобного фонарика/ПНВ
Пример использования. Найдите файл game_global.ltx
по пути gamedata/configs
, в нём есть две нужные нам секции - night_vision
и headlamp
. В указанных секциях есть соответствующие параметры, которые отвечают за аниматор включения и выключения Фонарика/ПНВ, headlamp_animator
- для фонарика, night_vision_animator
- для ПНВ соответственно. По умолчанию параметры ссылаются на секцию nvs_animator
, которая по умолчанию не существует. Можно, как и переопределить секцию, так и создать секцию nvs_animator
.
Использование через скрипты
Пример использования. В скрипты экспортированы принадлежности для запуска худ аниматора из под скриптов, например, для кат-сцены. Функции худ аниматора напрямую привязаны к актору, поэтому и запускать худ аниматор нужно, через него, используя db.actor. К примеру, нужно запустить кат-сцену, как ГГ использует какой-то предмет, или смотрит на документ, неважно.
function main_story_look_doc()
db.actor:start_hud_animator("look_doc_animator")
end
LUA функции худ аниматора
start_hud_animator(string) - Запускает худ аниматор, в аргументах нужно указать название запускаемой секции.
stop_hud_animator() - Останавливает проигрывание худ аниматора.
is_hud_animator_active() - Возвращает boolean, активный ли худ аниматор в данный момент.
get_hud_animator_section() - Возвращает string, название текущей секции худ аниматора.
get_hud_animator_restored_slot() - Возвращает u8, слот активного итема, который был спрятан для запуска худ аниматора.
get_hud_animator_force_hide_items() - Возвращает boolean, включено ли моментальное скрытие оружия перед запуском худ аниматора.
set_hud_animator_force_hide_items(boolean) - Аргумент указывает нужно ли моментально скрыть оружие перед запуском худ аниматора.
Содержание секции худ аниматора
Поскольку худ аниматор не требует фейкового предмета и/или слота под него, всё что требуется для его работы это секция с определенными параметрами.
[antirad_use]
item_visual = dynamics\weapons\wpn_eat\injectors\wpn_injector_antirad_hud.ogf ;Путь к визуалу, который хотим отобразить (Опционально, если нужны только руки, то данная строка должна отсутствовать)
;Позиция и ротация (аналогично с оружием)
hands_orientation = 0.000000,0.000000,0.000000 ;Ротация рук
hands_orientation_16x9 = 0.000000,0.000000,0.000000
hands_position = 0.000000,0.011600,0.015000 ;Позиция рук
hands_position_16x9 = 0.000000,0.011600,0.015000
; Звуки (аналогично с оружием)
sound_1 = interface\item_usage\antirad_use ;Путь к звуку, который хотим отыграть (Опционально, если звук не требуется, то данная строка должна отсутствовать)
; Если звуков несколько:
sound_1 = interface\item_usage\antirad_use
sound_11 = interface\item_usage\antirad_use1
sound_12 = interface\item_usage\antirad_use2
sound_13 = interface\item_usage\antirad_use3
;Анимация (аналогично с оружием)
anm_show = antirad ;Указывается, как и анимация итема, так и анимация рук, порядок аналогичен оружию, т.е. `anm_show = анимация рук, анимация итема`, если названия для анимаций рук и итема одинаковые, достаточно написать один раз, как в данном примере. Также можно указать скорость анимации, через запятую, после названий анимаций: `anm_show = antirad, 3.2`
;Запрет на бег
can_sprint = true ; Запрещает/разрешает бег во время проигрывания ЭТОГО аниматора, в зависимости стоит true или false, false - запрещает бег.
;Бленд анимации
blend = true ; Включает сглаживание с предыдущей анимацией худ аниматора. Видимых изменений особо видно не будет.
;Смена HUD FOV
hud_fov = 55 ; Указывается плавающее значение, которое устанавливается в качестве hud fov на время проигрывания худ аниматора.
; ПРИМЕЧАНИЕ. Все последующие описанные LUA вызовы по умолчанию равняются null, если есть необходимость в занулении ссылки на скриптовой вызов - пишете null.
;LUA. Модификация секции худ аниматора (подмена секции)
modify_sect_lua_callback = animator_callbacks.modify_exo_sect ; Скрипт.Функция, в функции всегда должен быть аргумент с любым названием, в него будет передаваться текущее название секции худ аниматора. В данном примере мы подменяем секцию антирада, если у нас надет экзоскелет:
;LUA. Проверка на доступность использования
precondition_functor = safe_zones.in_safe_zone ;Скриптовая функция, которая возвращает true/false, если возвращает false - худ аниматор не запустится, т.к. по какой-то причине описанной в вызываемом коллбеке мы не проходим проверку на разрешение запуска. В основном нужно для блокировки быстрого удара или быстрого броска гранаты в безопасных зонах.
;LUA. Различные коллбеки во время работы самого худ аниматора
;Примечание, названия left, left2, right, right2 не имеют ничего общего с руками, по умолчанию в сталкере моушен марки имеют только эти четыре названия в СДК.
start_lua_callback = null ; Вызывает скрипт при самом старте худ аниматора
end_lua_callback = null ; Вызывает скрипт в самом конце анимации худ аниматора
left_lua_callback = null ; Вызывает скрипт при достижении требуемого кадра в "Left" моушен марке
left2_lua_callback = null ; Вызывает скрипт при достижении требуемого кадра в "Left2" моушен марке
right_lua_callback = null ; Вызывает скрипт при достижении требуемого кадра в "Right" моушен марке
right2_lua_callback = null ; Вызывает скрипт при достижении требуемого кадра в "Right2" моушен марке
--Функция всегда должна возвращать string!!!
function modify_exo_sect(section)
if db.actor then
local outfit = db.actor:item_in_slot(7)
if outfit and (outfit:section() == "exo_outfit" or outfit:section() == "svoboda_exo_outfit") and ini:line_exist(section, "modify_exo_sect") then
return ini:r_string(section, "modify_exo_sect") --Читаем из секции худ аниматора параметр modify_exo_sect, который ссылается на секцию для аниматора антирада в экзоскелете
end
end
return section
end
Добавление моушен марок в анимацию
В этом примере используется фанатский софт OMF Editor. Откроем анимацию через любой софт, который поддерживает плагины на сталкерский формат анимаций, такие распространенные, как 3Ds Max, Blender и Maya имеют такие плагины. Поскольку в примере упор на работу в Blender, прилагается ссылка на плагин от PavelBlend для Blender.
Не буду расписывать весь процесс подгрузки анимаций и т.д., и т.п., важно только посмотреть анимацию и найти нужный кадр, на который мы повесим марку/марки.
В моём случае это шестидесятый кадр когда таблетки находятся за камерой. Этот кадр будет использоваться, к примеру, для вызова нужного скрипта.
Открываем OMF анимаций рук и ищем нужную анимацию, для удобства, выбираем в опции Motion time format
формат Keys
.
Чуть ниже ищем колонку, над которой написано Motion Marks
. Если она светится серым и лежащие в ней кнопки тоже серые, чуть выше опции Motion time format
есть колонка с галочками, нас интересует галочка Has Motion Marks
, включаем её.
В колонке Motion Marks
есть ещё две колонки, у которых есть кнопки Add
и Del
. В крайней колонке слева, жмём Add
. Поскольку худ аниматор рассчитан на оригинальные моушен марки Left
, Left2
и т.д. создаём только марки из меню, которое появится при нажатии на кнопку Add
, мне нужна Left
, поэтому я создаю именно её.
В левой колонке появилась наша марка, теперь жмём кнопку Add
в крайней колонке справа, если у нас самая первая одна единственная марка, то в правой колонке создастся элемент с названием 0_mark0
. Чуть правее колонок с марками есть строки Start
и End
, под ними есть поля, по умолчанию стартовое поле равняется нулю, а эндовое поле равняется длине анимации, у меня это 118 кадров. Эндовое поле ни в коем случае нельзя менять, иначе марка не будет работать корректно! Правим только стартовое. Ранее я нашёл в анимации нужный мне кадр - шестидесятый кадр.
Важное примечание, почти в самом верху, есть поле Speed
, оно отвечает за скорость анимации, а скорость влияет на вызов моушен марки, если скорость - 1, прописываем нужный кадр и не паримся. Если Speed
больше или меньше 1, то мы делим нужный кадр на скорость анимации, если б скорость анимации была 2, то пришлось бы ставить стартовое время не 60, а 30. Если анимация по ошибке была сделана в 60fps и выше, а скорость 2 выбрана специально, чтоб скрыть этот косяк, то тут уже совсем другая ситуация, которая в данном примере не рассматривается.
Работа в OMF Editor'е закончена. Сохраняем и закрываем. Поскольку я выбрал Left
марку, и я хочу сделать скриптовой вызов на эту марку, то в конфиге худ аниматора мне требуется прописать left_lua_callback
.
Важное примечание!! Моушен марки непосредственно используются в движке для вызова специальных функций, на том же аниматоре ПНВ используется Left
марка, на которую повешено включение ПНВ на нужном кадре. Движковые вызовы захардкодены только на аниматорах расходников, фонарика и ПНВ, и все они используют Left
марку по умолчанию, на данный момент, остальные марки не задействованы для движковых вызовов.
Обзор
[!IMPORTANT] Статус: Поддерживается Минимальная версия: 1.1
Система основывается на полноценном отдельном слоте (данный способ решает много проблем с детекторами/скрытием оружия/etc), из-за чего создаётся базовый предмет слота: anim_fake
, который нужно засунуть в инвентарь актора (можно при спавне).
anim_fake
misc/anim_slot.ltx
[anim_fake]:identity_immunities
class = F_ANMITM
slot = 22
can_trade = false
can_take = true
cost = 0
inv_weight = 0
inv_name = "animfake"
inv_name_short = "animfake"
default_to_ruck = false
sprint_allowed = true
; hud sect
animation_slot = 2
control_inertion_factor = 1
hud_fov = 45
hud = anim_fake
; For Debug
inv_grid_width = 1
inv_grid_height = 1
inv_grid_x = 11
inv_grid_y = 9
visual = dynamics\devices\dev_aptechka\dev_aptechka_low.ogf ; unused
; Hud attach
item_visual = dynamics\devices\dev_aptechka\dev_aptechka_low.ogf ; unused
attach_place_idx = 0
hands_position = 0, 0, 0
hands_orientation = 0, 0, 0
hands_position_16x9 = 0, 0, 0
hands_orientation_16x9 = 0, 0, 0
aim_hud_offset_pos = 0, 0, 0
aim_hud_offset_rot = 0, 0, 0
aim_hud_offset_pos_16x9 = 0, 0, 0
aim_hud_offset_rot_16x9 = 0, 0, 0
gl_hud_offset_pos = 0, 0, 0
gl_hud_offset_rot = 0, 0, 0
gl_hud_offset_pos_16x9 = 0, 0, 0
gl_hud_offset_rot_16x9 = 0, 0, 0
item_position = 0, 0, 0
item_orientation = 0, 0, 0
Из интересного тут только параметр hud_fov
, т.к. большая часть остальных переопределяется в секциях анимаций.
Параметры анимации
Секция строится следующим образом:
[my_hud_anim]
hands_position = -0.0055,-0.05, 0.32 ; Позиция рук
hands_orientation = -0.500000,1.000000,1.149999 ; Поворот рук
hands_position_16x9 = -0.0055,-0.05, 0.32 ; Позиция рук (16x9)
hands_orientation_16x9 = 2.349998,2.749999,2.849998 ; Поворот рук (16x9)
item_position = 0.000075,-0.004612,0.001283 ; Позиция предмета
item_orientation = 0.045015,1.047468,0.056850 ; Поворот предмета
item_visual = dynamics\weapons\wpn_eat\injectors\wpn_injector_big_antirad_hud.ogf ; Модель худ-анимации
anm_use = antirad_hands_eat_invtrans, antirad_wpn_eat ; Проигрываемая анимация (для предметов, не являющихся едой - можно указывать своё название)
attach_place_idx = 0
- Так же есть поддержка анимации использования предметов. Для этого достаточно содержимое секции выше перенести в секцию предмета
Проигрывание анимации
Если Вам нужно проиграть анимацию (кроме момента, с использование предмета), то можно вызвать луа функцию:
animslot.play("my_hud_anim", "anm_use")