Гайд Гайд по машине анимаций Valve.

Модератор форума
Участник
Статус
Оффлайн
Регистрация
26 Янв 2020
Сообщения
378
Реакции[?]
157
Поинты[?]
9K
Перед началом хочу выразить огромную благодарность AkatsukiSun за идею о написании этой работы.

В данной статье была использована информация с сайта
Пожалуйста, авторизуйтесь для просмотра ссылки.
(noad)

Начнем с предисловия. А именно с того, как вообще работают анимации в играх. Без понимания этого базиса будет очень сложно объяснить принцип работы машины анимаций Valve.

При построении анимаций в играх, используют несколько подходов, имеющих свои плюсы и минусы. Два наиболее распространенных сейчас:
1) Анимация будет вычисляться исходя из произвольного (физического) движения объекта в пространстве.
2) Смещение в пространстве будет исходить благодаря записанной анимации, игнорируя иные вмешательства.

Настоящее движение человека нелинейно — сначала мы наклоняемся вперед, затем выбрасываем ногу, и только потом начинаем движение, быстро ускоряясь после соприкосновения стопы с землей, и двигаемся по инерции до следующего шага. Нарисовать хотя бы простую прямолинейную анимацию хождения, которая будет учитывать все внешние факторы очень сложно. Что уж говорить о более сложных движениях — стрейфе, переходах между направлениями, торможением и поворотами.

Поэтому для достижения реализма нам в любом случае потребуется гигантский набор разнообразных клипов с движениями в различных направлениях, с различной скоростью, и т.п… Кроме того, анимационные клипы редко можно использовать изолированно, воспроизводя один за другим. Чаще всего в игре присутствует множество анимаций, между которыми не заготовлено специальных анимированных переходов.
Яркий пример из cs go:
Игрок бежит, и перезаряжается на ходу. Если бы в игре использовали поочередную смену клипов, то пришлось бы создавать огромное количество анимированных последовательностей для реализации данного действия.

Valve же используют очень интересный первый метод, прозванный animation layer машиной анимаций (кстати в юнити есть похожая штука).
Данная система призвана оптимизировать процесс анимации персонажа, при этом сохраняя высокий уровень реалистичности.

Принцип ее работы:
Существует набор слоев. Вы наверняка с ними уже знакомы, если нет, то советую перейти в данный тред: https://yougame.biz/threads/159096/ (thnks f33nRyv2 for shairing)
За каждым леером закреплены определенные файлы с записанной в них анимацией. Важно упомянуть, что одному слою принадлежит несколько таких файлов, в целях эргономики кода. А управлением выборов этих подтипов занимается функция SetLayerSequence(). Отсюда становится понятно, что sequence как раз отвечает за выбор анимационного клипа. Так, за 3 леером, больше известном как
ANIMATION_LAYER_ADJUST, закреплено 2 типа стоячей анимации:

1)ACT_CSGO_IDLE_ADJUST_STOPPEDMOVING - проигрывается в момент, когда игрок только только перешел из состояния движения в состояние покоя
Для прояснения ситуации, я сейчас и по ходу статьи буду использовать определенные выдержки из сервеной функции SetUpVelocity(). (важно заметить, что valve для обеспечения относительной безопасности игрового процесса, анимирует всех сущностей сугубо на сервере, клиент же занимается только отправкой пакетов, содержащих состояние клавиатуры, мыши, поворота модели и прочее, а так же отрисовкой анимации полученной с пакета с сервера. )
Итак, вернемся к слоям. Ниже привожу код, показывающий принцип выбора именно этой анимации:
C++:
bool bStartedMovingThisFrame = false;
    bool bStoppedMovingThisFrame = false;

    if ( m_flVelocityLengthXY > 0 )
    {
        bStartedMovingThisFrame = ( m_flDurationMoving <= 0 );
        m_flDurationStill = 0;
        m_flDurationMoving += m_flLastUpdateIncrement;
    }
    else
    {
        bStoppedMovingThisFrame = ( m_flDurationStill <= 0 );
        m_flDurationMoving = 0;
        m_flDurationStill += m_flLastUpdateIncrement;
    }

    // при соблюдении условия
    if ( !m_bAdjustStarted && bStoppedMovingThisFrame && m_bOnGround && !m_bOnLadder && !m_bLanding && m_flStutterStep < 50 )
    {

        //проигрывается анимация ACT_CSGO_IDLE_ADJUST_STOPPEDMOVING
        SetLayerSequence( ANIMATION_LAYER_ADJUST, SelectSequenceFromActMods( ACT_CSGO_IDLE_ADJUST_STOPPEDMOVING ) );
        m_bAdjustStarted = true;
    }

2) ACT_CSGO_IDLE_TURN_BALANCEADJUST - широко известная последовательность еще со времен фейков. Данный тип анимации проигрывается, когда игрок изменяет угол своего обзора более чем на 120 градусов. Вы и сами можете заметить в игре, что ноги игрока постепенно разворачиваются, когда тот изменяет угол своего обзора слишком сильно. (кстати за такое плавное разворачивание отвечает функция ApproachAngle).

ну и конечно выдержка из сетапа велосити:

C++:
    m_flFootYaw = ApproachAngle( m_pPlayer->m_flLowerBodyYawTarget.Get(), m_flFootYaw, m_flLastUpdateIncrement *  CSGO_ANIM_LOWER_CATCHUP_IDLE );

 
    if ( gpGlobals->curtime > m_flLowerBodyRealignTimer && abs( AngleDiff( m_flFootYaw, m_flEyeYaw ) ) > 35.0f )
    {
        m_flLowerBodyRealignTimer = gpGlobals->curtime + CSGO_ANIM_LOWER_REALIGN_DELAY;
        m_pPlayer->m_flLowerBodyYawTarget.Set( m_flEyeYaw );
    }

    if ( m_flVelocityLengthXY <= CS_PLAYER_SPEED_STOPPED && m_bOnGround && !m_bOnLadder && !m_bLanding && m_flLastUpdateIncrement > 0 && abs(            AngleDiff( m_flFootYawLast, m_flFootYaw ) / m_flLastUpdateIncrement > CSGO_ANIM_READJUST_THRESHOLD ) )
    {
        SetLayerSequence( ANIMATION_LAYER_ADJUST, SelectSequenceFromActMods( ACT_CSGO_IDLE_TURN_BALANCEADJUST ) );
        m_bAdjustStarted = true;
    }
Скажу пару слов о 6 леере, самом важном леере для анимации движения. Тот самый страшный для всех юных кодеров, которые хоть раз глядели на сетап велосити, код:
Пожалуйста, авторизуйтесь для просмотра ссылки.

Данный код занимается перемоткой цикла анимации в зависимости от входящих факторов (об этом немного ниже).

Теперь поговорим про такие важные составляющие класса лееров, как: Weight, Cycle, PlayBackRate, Sequence.

1)Weight - отвечает за степень условного "веса" анимационного клипа в конечной анимации. Позволяет смешивать несколько типов анимации (вспоминаем про пример перезаряжающегося на бегу игрока) . Важное уточнение, что в кс используется именно blending тип смешивания, когда слои накладываются друг на друга, а не замещаются каким то конкретным слоем.

2)Cycle - своеобразный "таймлайн" анимационного фрейма, позволяет выбирать, с какого момента будет воспроизводится записанный анимационный клип.

3) PlayBackRate - скорость воспроизведения анимации. С помощью этого параметра можно ускорять и замедлять воспроизведение анимации.

(Если говорить про аним ресольвер, то там как раз используется логика определения разницы в скоростях воспроизведения анимации, и на основе этого определяют, где находится реал (подсказка: там где разница в скоростях больше, там скорее всего и реал, но необходимо помнить, что нам необходимо просимулировать каждый сайд игрока, для получения корректной информации о состоянии лееров на предполагаемом сайде.))

4)Sequence - тут все просто. Как я уже и говорил, этот параметр отвечает за определенный подтип анимационного ролика, закрепленного за слоем.

Важно не забывать, что все параметры, кроме Sequence имеют диапазон значений [0; 1].

Вот и подошел к концу обобщающий гайд по анимациям. Если вам было интересно, и вы хотите продолжения, где я более подробно коснусь каждой из функций анимаций, то смело пишите об этом в коментариях.
 
Последнее редактирование:
Keep Ev0lving, Stay Fatal
Эксперт
Статус
Оффлайн
Регистрация
6 Фев 2018
Сообщения
1,550
Реакции[?]
585
Поинты[?]
101K
Участник
Статус
Оффлайн
Регистрация
15 Янв 2021
Сообщения
492
Реакции[?]
289
Поинты[?]
79K
Лена жестко пояснила про анимации игроков...

P.s. действительно полезная инфа, ньюкамыч взял на заметку. Побольше бы таких тем на юг, а то я попытался разбавить своим гайдом по анлоаду, а он в основном оказался говном, да и засрали ещё. Но, такие посты дают мотивацию изучать что-то новое, и самому писать крутяшки для знающих людей..
 
Последнее редактирование:
Участник
Статус
Оффлайн
Регистрация
27 Фев 2019
Сообщения
1,125
Реакции[?]
395
Поинты[?]
50K
Умничка, 5+. Наконец-то будет меньше вопросов. Ну и я нихуя не удивлен, что очередной "дохуя развитый" поставит клоуна.
 
kitty.
Пользователь
Статус
Оффлайн
Регистрация
17 Окт 2021
Сообщения
282
Реакции[?]
111
Поинты[?]
17K
Как такового смысла от подобных постов попросту нет, если человек, занимающийся разработкой чита, не может разобрать работу анимаций игры, то к конечному продукту у пользователя должны уже возникнуть вопросы. Новичкам данные темы тоже должны быть не интересны(они сами до этого дойдут в процессе изучения) ведь, изучив данный материал, нужно изучить ещё немало информации(этот кусочек ты нигде заюзать не сможешь, тем самым просто забив себе голову) для того, чтобы найти применение этому кусочку потому что изучение идёт по "ступеням", некоторые люди(например: большая часть пользователей югейма, сидящая в разделе "cоздание читов для CSGO") переходят с первых "ступеней" сразу на последние. За старание, конечно же, спасибо, но каждый разработчик должен доходить до этого сам.
 
When DiamondCore update?
Забаненный
Статус
Оффлайн
Регистрация
19 Ноя 2019
Сообщения
400
Реакции[?]
51
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Перед началом хочу выразить огромную благодарность AkatsukiSun за идею о написании этой работы.

В данной статье была использована информация с сайта
Пожалуйста, авторизуйтесь для просмотра ссылки.
(noad)

Начнем с предисловия. А именно с того, как вообще работают анимации в играх. Без понимания этого базиса будет очень сложно объяснить принцип работы машины анимаций Valve.

При построении анимаций в играх, используют несколько подходов, имеющих свои плюсы и минусы. Два наиболее распространенных сейчас:
1) Анимация будет вычисляться исходя из произвольного (физического) движения объекта в пространстве.
2) Смещение в пространстве будет исходить благодаря записанной анимации, игнорируя иные вмешательства.

Настоящее движение человека нелинейно — сначала мы наклоняемся вперед, затем выбрасываем ногу, и только потом начинаем движение, быстро ускоряясь после соприкосновения стопы с землей, и двигаемся по инерции до следующего шага. Нарисовать хотя бы простую прямолинейную анимацию хождения, которая будет учитывать все внешние факторы очень сложно. Что уж говорить о более сложных движениях — стрейфе, переходах между направлениями, торможением и поворотами.

Поэтому для достижения реализма нам в любом случае потребуется гигантский набор разнообразных клипов с движениями в различных направлениях, с различной скоростью, и т.п… Кроме того, анимационные клипы редко можно использовать изолированно, воспроизводя один за другим. Чаще всего в игре присутствует множество анимаций, между которыми не заготовлено специальных анимированных переходов.
Яркий пример из cs go:
Игрок бежит, и перезаряжается на ходу. Если бы в игре использовали поочередную смену клипов, то пришлось бы создавать огромное количество анимированных последовательностей для реализации данного действия.

Valve же используют очень интересный первый метод, прозванный animation layer машиной анимаций (кстати в юнити есть похожая штука).
Данная система призвана оптимизировать процесс анимации персонажа, при этом сохраняя высокий уровень реалистичности.

Принцип ее работы:
Существует набор слоев. Вы наверняка с ними уже знакомы, если нет, то советую перейти в данный тред: https://yougame.biz/threads/159096/ (thnks f33nRyv2 for shairing)
За каждым леером закреплены определенные файлы с записанной в них анимацией. Важно упомянуть, что одному слою принадлежит несколько таких файлов, в целях эргономики кода. А управлением выборов этих подтипов занимается функция SetLayerSequence(). Отсюда становится понятно, что sequence как раз отвечает за выбор анимационного клипа. Так, за 3 леером, больше известном как
ANIMATION_LAYER_ADJUST, закреплено 2 типа стоячей анимации:

1)ACT_CSGO_IDLE_ADJUST_STOPPEDMOVING - проигрывается в момент, когда игрок только только перешел из состояния движения в состояние покоя
Для прояснения ситуации, я сейчас и по ходу статьи буду использовать определенные выдержки из сервеной функции SetUpVelocity(). (важно заметить, что valve для обеспечения относительной безопасности игрового процесса, анимирует всех сущностей сугубо на сервере, клиент же занимается только отправкой пакетов, содержащих состояние клавиатуры, мыши, поворота модели и прочее, а так же отрисовкой анимации полученной с пакета с сервера. )
Итак, вернемся к слоям. Ниже привожу код, показывающий принцип выбора именно этой анимации:
C++:
bool bStartedMovingThisFrame = false;
    bool bStoppedMovingThisFrame = false;

    if ( m_flVelocityLengthXY > 0 )
    {
        bStartedMovingThisFrame = ( m_flDurationMoving <= 0 );
        m_flDurationStill = 0;
        m_flDurationMoving += m_flLastUpdateIncrement;
    }
    else
    {
        bStoppedMovingThisFrame = ( m_flDurationStill <= 0 );
        m_flDurationMoving = 0;
        m_flDurationStill += m_flLastUpdateIncrement;
    }

    // при соблюдении условия
    if ( !m_bAdjustStarted && bStoppedMovingThisFrame && m_bOnGround && !m_bOnLadder && !m_bLanding && m_flStutterStep < 50 )
    {

        //проигрывается анимация ACT_CSGO_IDLE_ADJUST_STOPPEDMOVING
        SetLayerSequence( ANIMATION_LAYER_ADJUST, SelectSequenceFromActMods( ACT_CSGO_IDLE_ADJUST_STOPPEDMOVING ) );
        m_bAdjustStarted = true;
    }

2) ACT_CSGO_IDLE_TURN_BALANCEADJUST - широко известная последовательность еще со времен фейков. Данный тип анимации проигрывается, когда игрок изменяет угол своего обзора более чем на 120 градусов. Вы и сами можете заметить в игре, что ноги игрока постепенно разворачиваются, когда тот изменяет угол своего обзора слишком сильно. (кстати за такое плавное разворачивание отвечает функция ApproachAngle).

ну и конечно выдержка из сетапа велосити:

C++:
    m_flFootYaw = ApproachAngle( m_pPlayer->m_flLowerBodyYawTarget.Get(), m_flFootYaw, m_flLastUpdateIncrement *  CSGO_ANIM_LOWER_CATCHUP_IDLE );


    if ( gpGlobals->curtime > m_flLowerBodyRealignTimer && abs( AngleDiff( m_flFootYaw, m_flEyeYaw ) ) > 35.0f )
    {
        m_flLowerBodyRealignTimer = gpGlobals->curtime + CSGO_ANIM_LOWER_REALIGN_DELAY;
        m_pPlayer->m_flLowerBodyYawTarget.Set( m_flEyeYaw );
    }

    if ( m_flVelocityLengthXY <= CS_PLAYER_SPEED_STOPPED && m_bOnGround && !m_bOnLadder && !m_bLanding && m_flLastUpdateIncrement > 0 && abs(            AngleDiff( m_flFootYawLast, m_flFootYaw ) / m_flLastUpdateIncrement > CSGO_ANIM_READJUST_THRESHOLD ) )
    {
        SetLayerSequence( ANIMATION_LAYER_ADJUST, SelectSequenceFromActMods( ACT_CSGO_IDLE_TURN_BALANCEADJUST ) );
        m_bAdjustStarted = true;
    }
Скажу пару слов о 6 леере, самом важном леере для анимации движения. Тот самый страшный для всех юных кодеров, которые хоть раз глядели на сетап велосити, код:
Пожалуйста, авторизуйтесь для просмотра ссылки.

Данный код занимается перемоткой цикла анимации в зависимости от входящих факторов (об этом немного ниже).

Теперь поговорим про такие важные составляющие класса лееров, как: Weight, Cycle, PlayBackRate, Sequence.

1)Weight - отвечает за степень условного "веса" анимационного клипа в конечной анимации. Позволяет смешивать несколько типов анимации (вспоминаем про пример перезаряжающегося на бегу игрока) . Важное уточнение, что в кс используется именно blending тип смешивания, когда слои накладываются друг на друга, а не замещаются каким то конкретным слоем.

2)Cycle - своеобразный "таймлайн" анимационного фрейма, позволяет выбирать, с какого момента будет воспроизводится записанный анимационный клип.

3) PlayBackRate - скорость воспроизведения анимации. С помощью этого параметра можно ускорять и замедлять воспроизведение анимации.

(Если говорить про аним ресольвер, то там как раз используется логика определения разницы в скоростях воспроизведения анимации, и на основе этого определяют, где находится реал (подсказка: там где разница в скоростях больше, там скорее всего и реал, но необходимо помнить, что нам необходимо просимулировать каждый сайд игрока, для получения корректной информации о состоянии лееров на предполагаемом сайде.))

4)Sequence - тут все просто. Как я уже и говорил, этот параметр отвечает за определенный подтип анимационного ролика, закрепленного за слоем.

Важно не забывать, что все параметры, кроме Sequence имеют диапазон значений [0; 1].

Вот и подошел к концу обобщающий гайд по анимациям. Если вам было интересно, и вы хотите продолжения, где я более подробно коснусь каждой из функций анимаций, то смело пишите об этом в коментариях.
Отлично.
 
sapphire dev
Пользователь
Статус
Оффлайн
Регистрация
15 Мар 2018
Сообщения
188
Реакции[?]
124
Поинты[?]
36K
Сижу я значит в чужом телефоне в армии, смотрю что же нового произошло на югейме, вижу тему про анимации, думаю, что сейчас пойду, но по факту правильно, хоть информации и маловато. Спасибо за упоминание моей кринжовой темы.
 
Последнее редактирование:
Сверху Снизу