Gamedev Владимир Семыкин
5 533

Уроки Unity: создание файтинга, основанного на физике

Практические советы по созданию ключевых аспектов системы.

В закладки
Аудио

Разработчик Луис Бермудес, ранее работавший в EA, Disney и Roblox Corporation, опубликовал в своём блоге на Medium текст, в котором расписал ключевые аспекты создания физической системы в файтинге. Также автор описал практические способы реализации этого в Unity.

В реальности физика работает таким образом, что при ударе в лицо, голова продолжает движение в том направлении, в котором был совершён удар.

Кроме того, голова будет поворачиваться в том же направлении, в котором был совершён удар. В этом конкретном случае лицо будет вращаться вокруг вертикальной оси Y. Голова в конечном итоге достигнет предела вращения, как показано на рисунке ниже.

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

В дополнение к вращению по вертикальной оси, есть также вращение по горизонтальной оси. Для повторения: сила удара будет перенесена на голову, и она будет вращаться в том же направлении, что и направление удара. В этом конкретном случае голова повернётся вокруг горизонтальной оси X (или Z). В конечном итоге голова достигнет предела вращения, как показано на рисунке ниже.

Также голова постарается вернуться в своё первоначальное положение, как показано на следующем рисунке.

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

Вот простой код, который делает именно это:

void FixedUpdate() { Vector3 ySpringTorque = getTorsionalSpringTorque (Vector3(0,1,0), Vector3(0,1,0)); Vector3 xSpringTorque = getTorsionalSpringTorque (Vector3(1,0,0), Vector3(1,0,0)); rigidBody.applyTorque(ySpringTorque); rigidBody.applyTorque(xSpringTorque); }

Моделирование и реализация

Как уже упоминалось, после каждого вращения голова возвращается в состояние покоя. Это можно смоделировать с помощью крутящего момента. Уравнение крутящего момента выглядит следующим образом:

T = q * r * a1 + p * w * a2

T — крутящий момент, q — константа жёсткости, r — расстояние от требуемого вращения в градусах, p — константа затухания силы, а w — разница между текущей угловой скоростью и требуемой угловой скоростью. Также a1 — это ось вращения, a2 — это ось вращения для угловой скорости. Части уравнения a1 и a2 не обязательно являются одним и тем же вектором оси вращения. Кроме того, если затухание силы не нужно, тогда p равна нулю, и выражение упрощается до:

T = q * r * a1

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

Vector3 getTorsionalSpringTorque (Vector3 axisOfRotation, Vector3 axisOfAngularVelocity) { float r_ij = desRot — currRot; float w_ij = desAngVel — currAngVel; Vector3 springTorque = Q * r_ij * axisOfRotation + P * w_ij * axisOfAngularVelocity; return springTorque; }

Важно понимать, что желаемого угла поворота можно достичь с помощью анимации — keyframes от аниматоров или данных с motion capture. Кроме того, константами q и p можно управлять, чтобы определить, насколько отзывчиво вращение. Это означает, что аниматор может контролировать, насколько быстро голова вернётся в нужное положение.

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

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

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

Это основные аспекты файтинга, основанного на физике: наличие оппонента, который реагирует на удары; определение места ударов и их силы. Нужно понимать, что понадобится большой объём данных анимации для создания широкого спектра ударов и реакций на них. Использование этих методов физики и кинематики позволяет генерировать большое количество анимаций без необходимости большого количества данных анимации. Также все эти методы распространяются на удар ногой.

#unity #основы

{ "author_name": "Владимир Семыкин", "author_type": "editor", "tags": ["\u043e\u0441\u043d\u043e\u0432\u044b","unity"], "comments": 15, "likes": 50, "favorites": 172, "is_advertisement": false, "subsite_label": "gamedev", "id": 50063, "is_wide": true, "is_ugc": false, "date": "Wed, 15 May 2019 11:22:58 +0300" }
Подкаст: эмоциональное
выгорание на работе
Слушать фоном🎧
{ "id": 50063, "author_id": 94357, "diff_limit": 1000, "urls": {"diff":"\/comments\/50063\/get","add":"\/comments\/50063\/add","edit":"\/comments\/edit","remove":"\/admin\/comments\/remove","pin":"\/admin\/comments\/pin","get4edit":"\/comments\/get4edit","complain":"\/comments\/complain","load_more":"\/comments\/loading\/50063"}, "attach_limit": 2, "max_comment_text_length": 5000, "subsite_id": 64954, "last_count_and_date": null }

15 комментариев 15 комм.

Популярные

По порядку

Написать комментарий...
3

Overgrowth. И ни слова больше.

Ответить
0

только игре не хватает полировки и вылизанности. и нет ответа на вопрос, чем люди столько лет занимались, пока её делали

Ответить
0

Работали над игрой в свое удовольствие. Один из братьев, например, параллельно делал игры для джемов, ну и часто побеждал. Честно говоря, у Overgrowth есть некий даунгрейд и неправильные геймдизайнерские решения по сравнению с оригиналом - Lugaru. Так что он тоже мастхэв.

Ответить
0

у меня есть в пример тоже команда энтузиастов, делающая на UE3 сетевой классовый шутер с техникой и космическими боями - Angels Fall First. игру тоже пилят по чуть-чуть, когда есть время и силы, но там явно виден прогресс, рост и работа над ошибками.

Авторы же Overgrowth будто топтались много лет на одном месте. я за игрой следил оч давно, когда они только в блоге своём видосы выкладывали, и основа - боевая система с динамической анимацией - у них была готова ооочень давно. но всё остальное выглядело крайне кустарно и топорно. я даже поддержал их ещё до выхода в ранний доступ в Стиме, и была надежда на вот прям крутой проект - да как вообще можно было зафакапить игру с такой боевой системой? но... у них это получилось

Ответить
0

А что там зафакапилось в твоем понима... Ненене, чего ты от игры ожидал? В игре есть сильная поддержка модов, благодаря ей мы имеем тот же Therium-2, который в игру добавили официально. Опять же свою точку зрения я уже выразил.

Ответить
0

Ничего конкретного не ждал, но увидел:
-страшные модельки персонажей - в частности, коты просто уродливы
-отвратительно сделанные уровни, авторы даже не старались скрыть их блочность
-объекты просто воткнуты в землю или поверхность, зачастую место стыковки никак не прикрыто ни - спрятано, не обтянуто особой текстурой, нет дополнительных обхектов
-катсцены из конца 90х, никакой постановки или режиссуры
-при всей навороченности динамической анимации персонажи в целом двигаются неестественно - напряжённые, зажатые, нет разнообразия

это не похоже на законченную игру

Ответить
0

1) Эта серия всегда была прежде всего о противостоянии зайцев и волков (больше о зайцах), так вот зайцы выглядят даже круче, чем в оригинале. А вот волков тупо сделали качками, ака оборотни, выглядит крипово, так еще их геймплей скатился до спама читерного удара в прыжке - победить нормально их нереально. Коты да, выглядят как соник из нового фильма - ужасно.
2)В игре сразу несколько кампаний, которые разительно отличаются по качеству друг от друга.
Кампания оригинала (Лугару) - была как раз такой, но это ничуть не мешало ей быть хорошой игрой (игра вроде 2005 года).
Кампания самого Overgrowth - сделана гораздо лучше и красивее, но блочные моменты тоже встречаются, разрабы как никак те же))
А вот фанатские Therium-2 и его продолжение Drika's Story совсем другое дело. Мало того, что они НЕЛИНЕЙНЫ (можно идти в разные локации, твои действия влияют на игру), так еще они имеют глубокий лор и хороший сюжет. Маленькая часть схематичности/блочности все равно остается, но это никак не бьет по восприятию, имхо, даже дает +1 к атмосфере. В плане геймплея все кампании хороши.
3)Я вообще как бы не приветствую катсцены (лучше делать как в халве), но чего ты хотел от маленького инди? Диалоги в игре меня устраивают.
4)Насчет напряженных и зажатых не понял. Анимации круты, ты чего, ими просто можно любоваться.

Игра законченная, а косяки можно исправить модами. Правда, которые еще нужно сделать, 2 года горю желанием исправить даунгрейд геймплея, но никак руки не доходят (я еще ни разу моды не делал)

Ответить
0

Кстати, как ты уже, наверное, понял, мой ник - имя гг, а ава - официальный арт по игре:)

Ответить
2

Ну что, теперь и файтинги на джеме от дтф будут?)

Ответить
3

Файтинги-дейтсимы

Ответить
2

Скотт Пилигрим уже был

Ответить
0

Файтинг-дейтсим-баттрояль-3-в-ряд?

Ответить
0

Вроде такое уже было по Сейлор Мун для сега сатурн

Ответить
2

получается, всё просто

Ответить
0

Название не соответствует тексту. Тема не раскрыта.

Ответить
0

Прямой эфир

[ { "id": 1, "label": "100%×150_Branding_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox_method": "createAdaptive", "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "ezfl" } } }, { "id": 2, "label": "1200х400", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "ezfn" } } }, { "id": 3, "label": "240х200 _ТГБ_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fizc" } } }, { "id": 4, "label": "240х200_mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "flbq" } } }, { "id": 5, "label": "300x500_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "ezfk" } } }, { "id": 6, "label": "1180х250_Interpool_баннер над комментариями_Desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "clmf", "p2": "ffyh" } } }, { "id": 7, "label": "Article Footer 100%_desktop_mobile", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fjxb" } } }, { "id": 8, "label": "Fullscreen Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fjoh" } } }, { "id": 9, "label": "Fullscreen Mobile", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fjog" } } }, { "id": 10, "label": "Native Partner Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyb" } } }, { "id": 11, "label": "Native Partner Mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyc" } } }, { "id": 12, "label": "Кнопка в шапке", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fdhx" } } }, { "id": 13, "label": "DM InPage Video PartnerCode", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox_method": "createAdaptive", "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "clmf", "p2": "flvn" } } }, { "id": 14, "label": "Yandex context video banner", "provider": "yandex", "yandex": { "block_id": "VI-250597-0", "render_to": "inpage_VI-250597-0-1134314964", "adfox_url": "//ads.adfox.ru/228129/getCode?pp=h&ps=clmf&p2=fpjw&puid1=&puid2=&puid3=&puid4=&puid8=&puid9=&puid10=&puid21=&puid22=&puid31=&puid32=&puid33=&fmt=1&dl={REFERER}&pr=" } }, { "id": 15, "label": "Плашка на главной", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "p1": "byudo", "p2": "ftjf" } } }, { "id": 17, "label": "Stratum Desktop", "provider": "adfox", "adaptive": [ "desktop" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fzvb" } } }, { "id": 18, "label": "Stratum Mobile", "provider": "adfox", "adaptive": [ "tablet", "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fzvc" } } } ]
Узнавайте новости о мостах
Санкт-Петербурга первыми
Подписаться на push-уведомления