Настройка idle актера human

Основные принципы

Список FSM-состояний, из которых возможен запуск idle-анимаций:

  • board - актер прилинкован к другому объекту;

  • lie_idle - лежит;

  • snipe - выглядывает из-за забора;

  • squat - сидит;

  • idle - стоит и ничем не занят.

Выбор idle-анимации происходит в два этапа:

1

Выбор запроса для Селектора анимаций

Логика выбора запроса описана в файле Селектора запроса \properties\animation_selector\human_idle_selector.set.

Опционально на данном этапе можно:

  • переключать состояние и/или задавать время блокировки семафоров ;

  • устанавливать новое FSM-состояние.

2

Выбор idle-анимаций

По выбранному на первом шаге запросу выбираются конкретные idle-анимации. Логика выбора описана в файле human_idle.inc, который является частью файла Селектора анимаций \properties\animation_selector\human.set

Для создания цепочек переключения idle-состояний в FSM хранится текущее idle-состояние актера.

Конфигурация Селектора idle-запроса

Синтаксис human_idle_selector.set

{init
	{state "<initial_state>"} ; обязательный параметр
	{semaphore "<name>" <time_from> <time_to>} 
}
{selector
	{if <condition>
		{idle
			{run "<request_name>"} ; имя запроса к Animation Selector
			{state "<new_state>"} ; при необходимости изменить состояние FSM
			{semaphore "<name>" <time_from> <time_to>} ; переопределение семафора
		}
	}
	[...]	
	{idle
		{run ""} ;запуск пустого запроса
	}
}
Компонент
Описание

{init ...}

Блок инициализации, вызывается при старте игры или спавне юнита. Задаёт начальное состояние FSM (state) и устанавливает блокировки семафоров (semaphore).

state "<initial_state>"

Устанавливает FSM-состояние актера сразу после его спавна. Обязательный параметр. Пример: "idle".

semaphore "<name>" <time_from> <time_to>

Блокирует или разблокирует семафор на указанное время (в секундах). Например, semaphore "can_smoke" 10 30 означает запрет курения на случайный срок от 10 до 30 сек.

{selector ...}

Основной блок, в котором происходит логика выбора запросов к Селектору анимаций в зависимости от текущего состояния FSM и условий.

{if <condition> ...}

Условная конструкция. Проверяет состояние FSM (fsm_tags, human_fsm_idle_state), активность семафоров (human_fsm_idle_semaphore), наличие взаимодействия актера с предметами (например, human_stuff holding) и другие параметры. Подробнее про синтаксис условий

{idle ...}

Блок для описания набора действий, исполняемых, если соответствующее условие выполнилось. Внутри блока задается команда run запуска запроса для Селектора анимаций. Опционально может задаваться смена состояния (state) и семафоров (semaphore).

run "<request_name>"

Команда активирует указанный запрос, который в дальнейшем используется в Селекторе анимаций (animation_selector/human.set). Пример: run "stand_smoking_begin". По имени запроса будет подобран соответствующий набор анимаций. Отсутствие указанного имени в команде означает запуск пустого запроса. При этом сохраняется текущая анимация актера.

Cостояния idle

В игре Men of War II используются два idle-состояния:

  • idle - играет обычные idle анимации;

  • smoking - играет анимации курения.

Семафоры в Селекторе idle-запросов

Семафоры применяются для управления частотой и условиями запуска определённых запросов. Они служат для задания временных ограничений, предотвращающих синхронное анимирование группы юнитов.

Синтаксис семафора

{semaphore "<semaphore_name>" N}

N - время блокировки семафора, в секундах.

Семафор может быть в 2-х состояниях:

  • разрешен - N=0;

  • заблокирован на указанное в N время.

Добавлять новые семафоры можно в блоке init

Семафоры idle-запросов, используемые в игре Men of War II
Имя семафора
Описание

can_smoke

Отвечает за доступность начала цикла курения. Пока семафор заблокирован, юнит не может вызвать запрос на начало курения (stand_smoking_begin). Блокируется после каждой сигареты, разблокируется через случайное время (например, 5–10 или 60–120 секунд).

can_inhale

Контролирует интервал между затяжками в процессе курения. Используется внутри состояния smoking для определения, когда можно вызвать запрос stand_smoking_process. После каждой затяжки блокируется на несколько секунд.

can_action

Разрешает проигрывание активных idle-действий (почёсывание, переминание и т. п.).

Пока семафор заблокирован, юнит будет воспроизводить только нейтральные idle, такие как stand_breath, squat_breath, lie_breath. Блокировка регулирует частоту смены анимаций.

stop_smoking

Семафор, ограничивающий возможность завершения курения. Когда активен, запрос stand_smoking_end не будет выполнен. Используется для задания минимального времени нахождения в состоянии smoking, чтобы курение выглядело реалистично.

Пример использования семафоров в Селекторе idle-запросов
{init
	{state "idle"}
	{semaphore "can_smoke" 10 30} ; don't smoke right away
	{semaphore "can_inhale" 3 5}
	{semaphore "can_action" 5 15} ; start from breathing
}
{selector
	[...]
	{idle
		{run "stand_smoking_begin"} ; animations request string from human_idle.inc
		{state "smoking"} ; set new state
		{semaphore "stop_smoking" 20 40} ; disable semaphore for seconds in range
		{semaphore "can_inhale" 3 5} 
	}
	[...]
}

Пояснения

Блок init

  • {state "idle"} Устанавливает стартовое состояние FSM юнита после спауна — idle (покой).

  • {semaphore "can_smoke" 10 30} Блокирует возможность начать курение сразу. Юнит сможет курить только через 10–30 секунд.

  • {semaphore "can_inhale" 3 5} Устанавливает интервал перед первой возможной затяжкой. Имеет значение, если юнит начнёт курить вскоре после появления.

  • {semaphore "can_action" 5 15} Задаёт паузу перед тем, как юнит сможет выполнять более активные idle-анимации, чем дыхание. Пока семафор заблокирован — проигрываются только idle-анимации дыхания.

Блок idle

  • {run "stand_smoking_begin"} Запускается запрос с именем stand_smoking_begin. Этот запрос будет передан в animation_selector/human.set, где будет выбран подходящий набор анимаций начала курения.

  • {state "smoking"} FSM-состояние юнита обновляется на "smoking" — это влияет на дальнейший выбор запросов и условий.

  • {semaphore "stop_smoking" 20 40} Устанавливает блокировку семафора stop_smoking на 20–40 секунд. Пока он активен, юнит не сможет завершить курение (вызов stand_smoking_end не сработает).

  • {semaphore "can_inhale" 3 5} Устанавливает паузу перед следующей затяжкой (например, для запуска stand_smoking_process в следующем цикле).

Условия

Составные условия в Селекторе idle-запроса записываются с помощью логических операторов and , or и not

Условия, которые используются в первую очередь:

  • {if human_fsm_idle_semaphore "can_smoke"

  • {if human_fsm_idle_state "smoking_begin"

  • {if fsm_tags "board"

Примеры условий в Селекторе idle-запроса ( human_idle_selector.set)
Условие
Значение

fsm_tags "board"

Проверка, есть ли у FSM-состояния тэг "board".

human_fsm_counter "forced_smoke" once

Проверка счетчика FSM "forced_smoke". Подробнее про проверку счетчиков

human_stuff holding "nothing"

Проверка, что у актера в руках ничего нет.

human_fsm_idle_state "idle"

Проверка текущего FSM -состояния при простое.

human_fsm_idle_semaphore "can_smoke"

Проверка, разрешен ли указанный семафор.

able "attention"

Проверка доступности способности attention.

not able "attention"

Обратная проверка — attention недоступен.

Пример вложенного составного условия в Селекторе idle-запросов
{if fsm_tags "up" 
    {if human_fsm_counter "forced_smoke" once and human_stuff holding "nothing" and human_fsm_idle_state "idle"
        {idle [...]}
    }
}

Используется двойное вложенное условие, где каждая часть должна быть выполнена, чтобы сработал соответствующий блок idle.

Проверка первого уровня: {if fsm_tags "up"} Этот блок обрабатывается только если FSM-состояние юнита помечено тегом "up" — например, стоит, находится вне укрытия и готов к действиям.

Проверка второго уровня:

Все три условия должны быть выполнены:

  1. human_fsm_counter "forced_smoke" once Проверяет значение счётчика forced_smoke:

    • если > 0, возвращает true и сбрасывает счётчик в 0;

    • если 0, возвращает false.

    Это механизм одноразового принудительного действия — использовать и обнулить.

  2. human_stuff holding "nothing" Проверяет, что в руках у юнита ничего нет (ни оружия, ни предметов).

    Если юнит держит что-то, то условие не выполнится.

  3. human_fsm_idle_state "idle" Проверяет, что текущее внутреннее состояние FSM в блоке idle — "idle".

    Это исключает конфликты с другими процессами (например, если юнит уже курит, то не запускать запрос повторно)

Варианты запроса для выбора idle-анимаций

Варианты имен запросов для команды run приведены в таблице ниже.

Для запросов *_idle предполагается какая-то серьёзная активность Для запросов *_breath - ожидаются анимации дыхания или небольшого шевеления

Запрос
Описание

stand_idle

stand_breath

Стоит

squat_idle

squat_breath

Сидит

snipe_breath

Смотрит из-за горизонтального укрытия (окопы, заборы по пояс)

lie_idle lie_breath

Лежит

stand_smoking_begin

Поджигает сигарету

stand_smoking_process

Делает затяжку

stand_smoking_end

Тушит сигарету

Можно добавлять свои запросы на анимации и прописывать соответствующую выборку анимаций в файле human_idle.inc.

Last updated