Часті помилки при створенні ігрових анімацій



Нещодавно я завершував етап розробки поточного ігрового проекту, і мені довелося виправляти безліч невеликих недоліків в даних і коді анімацій. Такі типи проблем часто зустрічалися мені і в минулих проектах. Трохи засмутившись, я почав записувати найпростіші поради та хитрощі, які я використовував раніше. Вони можуть бути корисними іншим розробникам, які розпочинають роботу з ігровою анімацією.

Відгук на сигнали джойстика тільки після їх стабілізації
У сучасних геймпадів зазвичай є не тільки цифрові кнопки, але і аналогові тригери з джойстиками; кожен з них може виводити практично нескінченну кількість значень. Джойстики можуть передавати будь-який кут від 0 до 360 градусів і радіус відхилення від 0 до 1. Тригери, хоча і схожі на двійкові кнопки, можуть видавати будь-нормалізоване значення від 0 до 1 — вони чутливі до тиску.

Важливо враховувати цю різницю, прив'язуючи аналогове управління до ключових моментів дій і анімацій персонажа. Користувачам потрібен певний час для зміни значення будь-якого аналогового елемента управління з 0 на 1. Якщо в цьому діапазоні є кілька сегментів, які використовуються для активізації різних типів дій, деякі проміжні стани аналогового управління можуть викликати несподівані для користувача дії в грі.

Наприклад, зазвичай гравці можуть поворачиватьтся на 180 градусів з допомогою джойстика двома різними способами (див. малюнок нижче).


Різні способи зміни відхилення джойстика на 180 градусів

В обох випадках може виникнути проблема. У разі зліва це пов'язано з проходженням джойстика через вихідне положення. Іноді ігри помилково інтерпретують це як сигнал для включення зупинки анімації персонажа, тому що положення джойстика має нульовий радіус. В нашому поточному проекті ми не допускаємо переривання анімації зупинки, поки не завершена частина анімації уповільнення, тому користувач не може негайно почати рухатися знову, якщо він збирався відхилити джойстик в іншому напрямку. У разі праворуч гра може спробувати виконати поворот на 90 градусів, якщо єдиним критерієм для джойстика є знаходження в певному сегменті кола.

Зрозуміло, якщо спрацював дія або анімацію можна відразу ж припинити, то воно буде замінено після того, як гравець до кінця поверне аналоговий джойстик, і в якійсь мірі цю проблему можна ігнорувати. У разі, якщо спрацював дія не переривається, гравцеві доведеться чекати завершення попередньої дії, щоб отримати очікувану реакцію. Це навіть може призвести повного ігнорування вводяться їм натискань.

Щоб попередити такі випадки, можна ввести для джойстика або будь-якого іншого елемента аналогового введення критерій стабілізації. Ми можемо взяти середнє значення з кількох останніх кадрів аналогового введення і порівняти його з поточним значенням. Таким чином ми чисельно визначимо, стабілізовано чи аналоговий ввід і чи слід його враховувати. Або ж він продовжує швидко змінюватися і реакцію на нього потрібно відкласти. Такий підхід значно знижує кількість хибнопозитивних реакцій, генеруючих спрацьовування дій за допомогою аналогового вводу. Головним недоліком тут стає латентність управління протягом декількох кадрів. Однак при використанні цього принципу у багатьох рухах персонажа в моєму поточному проекті при правильному налаштуванні ніхто з користувачів не міг помітити різниці.

Достатню кількість кадрів анімації, перекриває змішування
Багато персонажі у відеоіграх — справжні атлети. Вони можуть втекти з високою швидкістю, стрибати, знову бігти, маневрувати на бігу, зберігаючи велику інерцію. Тому у відеоіграх при переході від однієї дії до іншого надзвичайно важливо зберігати плавність і правдоподібність переходів і рухів персонажа. Один із способів забезпечення плавності — додавання додаткового часу на змішування між рухами. Це дозволить зберігати плавність переходів від одного анімації до іншої. Однак, щоб це працювало добре, в процесі змішування необхідно продовжувати оновлення завершальній або залежною анімації і рухатися відповідно інерції персонажа.

Якщо рух, що залишився для завершальній анімації, коротше тривалості змішування між анімацією і наступної, то алгоритм змішування в якості нижчої анімації буде використовувати статичну позу без певної швидкості. Часто це інтерпретується грою як нульова швидкість. В залежності від ваги змішування, що залишився для залежною анімації, такий різкий перехід залежною анімації до нульової швидкості може створити уривчастість змішаної швидкості персонажа при переході.


Зміна швидкості персонажа при переході між анімаціями A і B

У нижньому разі змішана швидкість містить уривчастість, викликану різким падінням до нуля швидкості залежною анімації. У верхньому прикладі швидкість персонажа в процесі змішування залишається саме такою, яку ми очікуємо завдяки великій кількості кадрів, що залишилися від точки переходу в залежній анімації.

Намагайтеся не втрачати значущі дії при змішуванні з ассетами
Більшість дій, виконуваних персонажем, складається з підготовки, самого діяння і його завершення. Якщо прибрати хоча б один з цих сегментів, персонаж буде виглядати неприродно. Наприклад, уявіть бейсболіста, намагається вдарити без замаху і завершення удару. На жаль, такі неприродні переходи у відеоіграх створювати занадто просто.

Цей ефект дуже помітний в іграх про баскетболі, де гравець з м'ячем постійно веде м'яч, ударяючи ним об підлогу і ловлячи його на відскоку. Іншими словами, він майже завжди або замахується, щоб ударити м'ячем об підлогу, або завершує рух, ловлячи їх у повітрі. Для завершеності кожен із сегментів удару м'ячем і його подальшого затримання повинен програватися повністю, інакше дриблінг буде виглядати неприродно. Потрібно бути дуже уважним до переходів протягом кожного з сегментів, щоб їх можна було замінити чимось, плавно продовжують процес підготовки, дії і завершення. Часто виникає проблема при переході до нового ассету, що містить сегмент очікування прямо на початку анімації. Якщо процес змішування переходу занадто довгий, гравці не побачать підготовки до дії в анімації, тому що триватиме попередня анімація. Вийшло в грі рух буде виглядати не дуже реалістично.

Існують способи виправити ситуацію динамічним зміною типу або довжини змішування переходу. Проте краще всього в цьому випадку — взагалі уникати цих проблем, створюючи ассеты таким чином, щоб в анімації не було ніяких обов'язкових поз, поки поточна анімація не досягла достатньої ваги в змішуванні. Завдяки цьому підготовка, дія і завершення будуть чітко видні на екрані. Приклад: якщо ви змішуєте анімацію бейсболіста, готового замахнутися битою, і у вас є довгий змішування з анімацією, то не змушуйте бейсболіста починати рух замаху битою в ассетах анімації занадто рано.

Scaling source motion rather than adding or subtracting
Часто нам потрібно додати до анімації рух, щоб персонаж досяг певної точки для взаємодії. Наприклад, крок персонажа вперед, щоб наблизитись до дверної ручки. Ігор часто доводиться перетворювати рух анімації в процесі виконання, щоб інверсна кінематика наблизив руку персонажа досить близько до ручки. В цьому випадку не потрібно додавати рух, який має відбуватися з постійною швидкістю протягом всієї анімації, Замість цього варто помітити, коли анімація рухається, і перетворити швидкість руху з урахуванням необхідної величини додаткового руху. Іншими словами, якщо персонаж в якихось сегментах анімації нерухомий, то до цих сегментів не варто додавати рух. В іншому випадку можуть виникнути така ситуація: персонаж повинен стояти, але замість цього він рухається, і його ноги ковзають по підлозі.


Швидкість персонажа з доданими 20% руху. Обома пунктирними лініями проходиться однакову відстань.

На малюнку вище ми беремо графік швидкості анімації, починається з певної швидкості і сповільнення до стану спокою. Для гри нам потрібно додати ще 20% рухи персонажа під час анімації. В одному з випадків ми вирішили додати додатковий рух на кількість кадрів анімації, і рівномірно розподілити його по кожному карту. В результаті персонаж продовжує зберігати ненульову швидкість навіть біля завершення, коли знаходиться в стані очікування. У другому випадку ми додали 20% рухи, просто отмасштабировав весь графік швидкості на 20%. Тепер персонаж рухається швидше в частинах анімації з рухом і залишається нерухомою при зазначеній в анімації нульової швидкості.

В одній із старих систем, з якою я працював, ми змусили персонажа стрибати вгору на певну висоту наступним чином: анімація зазначалося час відриву від землі і приземлення, а потім алгоритм розраховував додаткову величину зміщення, потрібного персонажа, щоб досягти певної висоти. Потім він рівномірно розподіляв це додатковий рух між моментами відриву від землі і приземлення. Ні в одному з випадків нам так і не вдалося зробити це рух природним, тому що ми ігнорували занадто багато з базового руху. На наступний рік ми переписали систему і вона стала масштабувати вертикальну швидкість персонажа для правильного відповідності стрибка. Результати виглядали набагато більш природно. Так вийшло тому, що частини стрибка, в які персонаж ще не рухався вгору, залишалися приблизно однаковими, і ми набирали швидкість лише коли персонаж вже рухався швидко. Взявши за основу дані про сьогодення дії і виконуючи зміни для відповідності певним позначок, ми досягли набагато кращих візуальних результатів.

Управління якістю великої кількості анімацій
За останні кілька років у мене була можливість попрацювати над багатьма спортивними відеоіграми. В іграх такого типу є цікава складність: вони намагаються відтворити точні рухи конкретних спортсменів з реального світу. У більшості ігор існує тільки одна анімація для одного типу ігрового дії. Нам же іноді доводилося створювати десятки різних варіацій, щоб ігрові спортсмени більш точно відповідали своїм реальним прототипам. Так з'являється великий обсяг ігрових анімацій, і будь-яка операція, яку потрібно виконати для кожної анімації вручну займає купу часу розробки. Просто уявіть, що для нової функції раптово потрібно вручну додати новий тег в сотні різних ассетов: це займає багато часу!

У подібних ситуаціях корисно мати фреймворк, який дозволяє виконувати верифікацію даних і створювати виправляють скрипти для декількох або всіх ассетов анімацій. Такі скрипти можуть виконувати верифікацію по певному набору правил, створюючи список ассетов, що вимагають ручної перевірки, автоматично усувати проблеми або навіть додавати метадані в певні моменти потрібних ассетов.

Зазвичай краще виправляти такі проблеми з даними заздалегідь. Інакше усунення помилок в процесі їх появи може зайняти дуже тривалий час. До того ж вам доведеться переривати поточну роботу для виправлення таких помилок з даними. Як правило, коли я витрачаю сили на скрипти верифікації даних, я економлю набагато більше часу порівняно з вирішенням проблем по мірі їх появи. Крім того, набравшись досвіду в реалізації таких скриптів, ви зможете краще і швидше створювати нові. Якщо у вас є скрипти, ви зможете швидко перевіряти всі ассеты на наявність нових анімацій з проблемами. Це досить корисно при розробці, коли нові анімації постійно додаються в гру.

Поділіться зі мною своїми думками
Сподіваюся, мої поради допоможуть вам заощадити кілька годин праці в процесі розробки. Принаймні, деякі з цих порад можуть допомогти створити середовище, в якому буде простіше масштабувати кількість анімацій і переходи анімацій у вашому проекті. Якщо вам є що сказати з приводу цих рад, або у вас є власні корисні рекомендації по роботі з ігровою анімацією, то напишіть мені на jcdelannoy@gmail.com. Спасибі!
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.