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

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

**Принцип работы Animation Selector**&#x20;

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

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

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

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

Примеры:

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

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

***

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

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

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

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

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

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

Примеры:

* `stand_idle`&#x20;
* `walk`&#x20;
* `lie_holdback_in`&#x20;

***

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

#### **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`.&#x20;

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

{% hint style="info" %}
В [Селекторе idle-запросов](/documentation/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"}
> }
> ```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bestway-1.gitbook.io/documentation/gem-rts-v1-ru/animacii/anymatsyonnaia_systema_yunytov/animation_selector.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
