Прототип v0.1
Автор: Skyblade
Идея
Недавно мне пришла в голову сделать хардкорную аркаду, в которой управление будет только с геймпада.
Если сильно упростить описание механики, то получится симулятор человека-паука.
Хотя я не думал в тот момент ни о человеке-пауке, ни об Атаке титанов, но в итоге захотелось сделать такое управление, которое будет позволять двигаться так же, как двигаются герои в означенной анимешке.
Так что я взял свой любимый Unity3D и начал изучать, как можно реализовать такое управление.
Небольшое уточнение для тех, кто не видел аниме - в нём герои перемещаются при момощи двух стальных тросов, которые крепятся по бокам. Тросы выстреливаются в 2 точки, затем герой, управляя натяжением каждого из тросов (+ реактивной тягой), может перемещаться в пределах того, что позволяет физика.
Джоинты такие джоинты
Реактивная тяга мне не нужна, поэтому для модели тросов я решил использовать Distance Joint 2D.
До того, как утвердился с выбором, я попробовал применить Spring Joint 2D с высоким значением Damping Ratio, чтобы сымитировать короткий разгон механизма натяжения троса, но эффект получился ожидаемо неподходящим - второй трос тоже реагировал на движение всей системы как пружина, и движение получалось слишком инерционным.
Какого #$%& ГГ останавливается в полёте?
Однако, если кому-то кажется, что с Distance Joint 2D было всё гладко, то это не так.
Сначала я пытался просто уменьшать значение свойства Distance у обоих видов джоинтов. Казалось бы, самый простой, очевидный и надёжный способ сымитировать втягивание троса, но нет.
Как оказалось, изменение длины джоинта работало, как часы, только если изменять это свойство в инспекторе. Если пробовать менять его через код, то ГГ не двигался. Вообще.
Немного поразмыслив, я пришёл к выводу, что надо сначала переместить ГГ чуть влиже к точке крепления, а уже затем укорачивать трос, т.к. само изменение длины джоина не прикладывает никаких к сил к объекту и не инициирует расчёт физики.
К счастью, этот вариант сработал. К несчастью, он заставил писать код для перемещения ГГ самому.
Это код был довольно простым - по нажатию кнопки тело на конце троса начинало двигаться от или к концу троса с постоянной скоростью.
Тяп-ляп - и физика готова
Итак, у меня был код, который двигал главного героя вдоль тросов, но теперь надо было научиться отцепляться от них и двигаться дальше по инерции.
Тут меня ждало второе разчарование - тело двигалось, как задумано, пока было прикреплено к тросам, но при их удалении оно не двигалось дальше по инерции. Вместо этого оно мгновенно останавливалось в воздухе в момент отпускания тросов независимо от скорости и направления движения.
Немного погуглив и поразмыслив, я пришёл к новому выводу, что я перемещаю ГГ неправильно - напрямую влияя на его скорость, я нарушаю нормальную работу физического движка.
Поэтому я решил перемещать тело путём приложения силы к нему.
Но как в этом случае ограничить скорость движения тела вдоль троса? Если просто прикладывать постоянную силу, то ГГ будет ускоряться, пока не кончится трос. Это явно не та модель движения, которая задумывалась мной.
Так как я не особо силён в физике, а хоть какой-нибудь результат получить очень хотелось, я решил применить единственный известный мне закон расчёта сил сопротивления, действующих на тело в жидкости, который позволяет ограничить скорость движения тела (спасибо форумчанам за формулу: http://www.gamedev.ru/code/forum/?id=87804&page=2#m21)
В итоге получилось примерно так, как было задумано – ГГ ускорялся, но его максимальная скорость стала ограниченной, а при отпускании троса он продолжал движение в соответствии с законами физики.
Видео прототипа: