> For the complete documentation index, see [llms.txt](https://docs.bestway.com.ua/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.bestway.com.ua/gem-rts-v1-ru/animacii/anymatsyonnaia_systema_yunytov/animation_selector.md).

# Настройка выбора анимации

**Animation Selector** — это набор конфигурационных файлов, используемых для задания правил выбора и воспроизведения анимаций в зависимости от текущего состояния конечного автомата состояний (FSM) юнита.

**Принцип работы Animation Selector**

При переходе юнита в новое состояние, обработчик состояния обращается к файлам Animation Selector, чтобы определить, какая анимация должна быть воспроизведена. В файле задаются:

* наборы анимаций, доступные для данного состояния;
* условия выбора конкретной анимации (например, в зависимости от позы, оружия, направления взгляда);
* приоритеты и fallback-анимации.

Для каждого описания FSM в ресурсах есть одноименный файл Animation Selector (далее по тексту - Селектор).

**Описания Селекторов** хранятся в папке `\properties\animation_selector\` . Файлы имеют расширение `.set`.

Примеры:

* `human.set` — используется для объекта `human`.
* `animal.set` — используется для объектов животных, например, `horse`.

**Файлы анимаций** размещаются либо в папке соответствующего объекта, либо в общем каталоге: `\properties\animation\` и его подкаталогах.

***

## Структура описания селектора

Описание селектора включают следующие элементы:

* [Имя запроса](#imya-zaprosa)
* [Условие](#usloviya-v-animation-selector) ;
* [Указание анимации](#sposoby-ukazaniya-animacii);
  * [Скорость проигрывания анимации](#skorost-animacii) .

{% hint style="info" %}
Для упрощения редактирования и повторного использования, рекомендовано выносить смысловые и повторяющиеся блоки выбора анимаций в отдельные `.inc`-файлы.\
Например, в ресурсе **Men of War II** файл `human.set` подключает смысловые блоки через `include` из внешних файлов.
{% endhint %}

### Имя запроса на выбор анимаций

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

Примеры:

* `stand_idle`
* `walk`
* `lie_holdback_in`

***

### Способы указания анимации

#### **1. Конкретная анимация** указывается с помощью блока параметра `anm`:

> Синтаксис для выбора конкретной анимации
>
> ```
> {anm "animation_name"}
> ```

* **Имя анимации** указывается в **двойных кавычках**.
* Запись `" "` означает **пустую анимацию -** новая анимация не будет запущена, а текущая анимация сохранится.

<details>

<summary>Пример выбора анимации с указанием конкретной анимации</summary>

```
{lie_belt_in
	{if human_stuff holding "pistol"
		{anm "lie_take_pistol" -1}
	}
	{anm "lie_put_small" 0.75}
}
```

* `lie_belt_in` - имя запроса
* блок `if` - условие для запуска анимации
* `lie_take_pistol` - имя анимации, которая проигрывается со скоростью `-1` ( минус означает, что анимация будет проигрываться с конца в начало)
* `lie_put_small` - имя анимации, которая проигрывается со скоростью `0,75`

</details>

#### **2. Случайный выбор анимаций**

Блок параметра `random_select` позволяет задать список альтернативных анимаций с различной вероятностью выбора:

> Синтаксис для случайного выбора анимаций
>
> ```
> {random_select
>     {weight n1 "animation_1"}
>     {weight n2 "animation_2"}
>     ...
> }
> ```

Параметр `weight` задаёт относительную вероятность выбора `n` в диапазоне от `0.01` до `100`.

{% hint style="info" %}
Названия анимаций записываются в двойных кавычках.
{% endhint %}

<details>

<summary>Пример случайного выбора анимации по ее весу</summary>

<pre><code><strong>{squat 
</strong>    {random_select
        {weight 5 "squat_idle_rifle_2"}
        {weight 2 "squat_idle_rifle_3" -1}
        {weight 1 "squat_idle_rifle_4"}
        {weight 1 "squat_idle_rifle_5"}
        {weight 1 "squat_idle_rifle_6"}
    }
}
</code></pre>

* Анимация `squat_idle_rifle_2` с весом `5`
* Анимация `squat_idle_rifle_3` с весом `2` и скоростью проигрывания `-1` (проигрывается с конца к началу)

</details>

#### 3. Выбор анимаций по счетчику

Циклическое переключение наборов анимаций на основе числового счётчика реализуется с помощью управляющего блока `switch_by_counter`. Конструкция используется для создания вариативных анимаций — таких как позы, походки, реакции, эмоциональные состояния и другие повторяющиеся состояния персонажа.

> **Синтаксис выбора анимаций по счетчику**
>
> ```
> {switch_by_counter <counter_name> 
>     {common [...]}   
>     {pick <N> [...]}
>     {pick <N> [...]} 
> ...
> }
> ```

<table><thead><tr><th width="177.4296875">Параметр</th><th>Назначение</th></tr></thead><tbody><tr><td><code>&#x3C;counter_name></code></td><td>Имя счётчика, определяющего текущее состояние переключения</td></tr><tr><td><code>common</code></td><td>(Опционально) Параметр для назначения базового набора анимаций, который копируется в каждый pick перед его применением</td></tr><tr><td><code>pick &#x3C;N></code></td><td>Вариант выбора анимаций.<br>Значение N означает, сколько шагов счётчика подряд будет применяться этот pick.</td></tr></tbody></table>

**Механика выбора анимаций по счетчику**

1. Счётчик начинается со значения `0`, при этом выбираются анимации из первого в списке `pick`.
2. При каждом вызове счетчика его значение увеличивается на `1`, переходя к следующему варианту выбора.
3. Счетчик работает по кольцу: если значение счётчика становится равно сумме всех значений `<N>`, взятых из `pick` — его значение сбрасывается в `0`
4. Внутри каждого `pick`, перед применением, копируются значения анимаций, указанных в `common`, после чего они перезаписываются данными из текущего `pick`, если такие есть. Таким образом, `pick` может:
   * наследовать `common` ,
   * переопределять нужные поля,
   * дополнять базовый набор анимаций из common новыми ключами.

{% hint style="warning" %}
Базовый набор анимаций (блок `common`) может отсутствовать. В таком случае все наборы анимаций берутся непосредственно из каждого `pick`.
{% endhint %}

<details>

<summary>Пример выбора анимаций по счетчику</summary>

```
{switch_by_counter "pose"    
    {common
        {aim "aim_default_1" "aim_default_2"}
        {fire "fire_default_1" "fire_default_2"}
    }
    {pick 1} 
    {pick 2
        {aim "aim_alt_1" "aim_alt_2"}
        {fire "fire_alt_1" "fire_alt_2"}
    }
    {pick 1
        {idle "idle_look_around"}
    }
    {pick 1
        {idle "idle_gun_aside"}
    }
}
```

Количество шагов счетчика `pose` в цикле равно сумме всех `N` в блоках `pick`: `1+2+1+1=5`

<table><thead><tr><th width="85.58984375">Шаг</th><th width="160.1796875">Значение pose</th><th width="220.76171875">Выбор блока pick</th><th>Выбор анимаций</th></tr></thead><tbody><tr><td>1</td><td>0</td><td>Первый блок <code>pick</code></td><td>Полностью берутся значения анимаций из блока <code>common</code> (переопределений нет)</td></tr><tr><td>2</td><td>1</td><td>Второй блок <code>pick</code></td><td>Значения параметров из блока <code>common</code> для <code>aim</code> и <code>fire</code> переопределяются на значения, указанные в текущем блоке <code>pick</code></td></tr><tr><td>3</td><td>2</td><td>Второй блок <code>pick</code></td><td>Значения параметров из блока <code>common</code> для <code>aim</code> и <code>fire</code> переопределяются на значения, указанные в текущем блоке <code>pick</code></td></tr><tr><td>4</td><td>3</td><td>Третий блок <code>pick</code></td><td>Значения параметров <code>aim</code> и <code>fire</code> берутся из блока <code>common</code> .<br>В набор анимаций добавляется анимация <code>idle</code></td></tr><tr><td>5</td><td>4</td><td>Четвертый блок <code>pick</code></td><td>Анимация <code>idle</code> заменяется на указанную в текущем <code>pick</code>, значения анимации <code>aim</code> и <code>fire</code> остаются соответствующими значениям из <code>common</code></td></tr><tr><td>6</td><td>5 → сброс в 0</td><td>Снова первый блок <code>pick</code></td><td>цикл повторяется, начиная с первого шага</td></tr></tbody></table>

</details>

### Скорость анимации

Скорость проигрывания анимации задаётся числом, следующим после имени анимации.\
Пример:

```plaintext
{anm "animation_name" 0.75}
```

* Если скорость анимации не указана, то используется значение по умолчанию: `1.0`
* **Отрицательные значения скорости** — означает реверсное воспроизведение анимации.

### Условия в Селекторе анимаций

Система `Animation Selector` поддерживает использование условий, позволяющих адаптировать выбор анимации к контексту текущего состояния или окружения актёра.

Условия задаются внутри блока `if` и могут быть:

* одиночными,
* составными,
* вложенными.

В качестве условий могут использоваться любые условия, подходящие для данного типа актера.\
Если условие срабатывает, выбор анимации осуществляется только среди вложенных в этот блок вариантов.\
Если ни одно условие не выполнено и не задана анимация по умолчанию, то активная анимация остаётся без изменений.

> **Синтаксис условия в Селекторе анимаций**:
>
> ```
> {if [condition]  
>     [...] ;anm или random_select
> }
> ```

Условие может быть простым или составным.\
В случае составного условия его части перечисляются через пробел, что является аналогом логического оператора `and`.

> **Синтаксис составных условий**
>
> ```
> {if cond1 cond2 cond3
>     [...]
> }
> ```

{% hint style="info" %}
В [Селекторе idle-запросов](/gem-rts-v1-ru/animacii/anymatsyonnaia_systema_yunytov/animation_selector/nastroika-idle.md#konfiguraciya-selektora-zaprosa) в составных условиях могут использоваться условные операторы `not` и `or`.
{% endhint %}

В описаниях выбора анимаций поддерживаются вложенные условия.

> **Синтаксис вложенных условий**:
>
> ```
> {if cond1   
>     {if cond2
>         {anm "animation_1"}
>     }
>     {anm "animation_2"}
> }
> ```
