DoubleRope

Прототип v0.1

Автор:

Идея
Недавно мне пришла в голову сделать хардкорную аркаду, в которой управление будет только с геймпада.

Если сильно упростить описание механики, то получится симулятор человека-паука.
Хотя я не думал в тот момент ни о человеке-пауке, ни об Атаке титанов, но в итоге захотелось сделать такое управление, которое будет позволять двигаться так же, как двигаются герои в означенной анимешке.

Так что я взял свой любимый 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)

В итоге получилось примерно так, как было задумано – ГГ ускорялся, но его максимальная скорость стала ограниченной, а при отпускании троса он продолжал движение в соответствии с законами физики.

Видео прототипа:

Запустить видео по клику - Как делать игрыЗапустить видео по клику - Как делать игры

+ Скриншоты
+ Скачать

Управление:
Левый аналоговый стик - прицеливание левым тросом.
Правый аналоговый стик - прицеливание правым тросом.
L1 - выстрел левым тросом.
R1 - выстрел правым тросом.

Если на пути троса есть стена и она достаточно близко, то трос прикрепится к стене до тех пор, пока кнопка не будет отпущена.

Когда трос прикреплён к стене, стик отвечает за то, какая сила прикладывается вдоль троса:
стик направлен к точке крепления – длина троса уменьшается,
стик направлен от точки крепления - длина троса увеличивается.

Замечания по геймпадам:
Для тестирования использовался геймпад Rumble Gamepad F510.  Названия его осей и кнопок в настройках Unity совпадают с названиями осей и кнопок DualShock.
Если у вас геймпад от Xbox или совместимый с ним, то перед запуском игры нужно будет переназначить пару осей:

+ Картинка

Нужно будет заменить эти 2 оси на
Joystick 1 axis 3 и
Joystick 1 axis 4 соотвественно.

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

Кроме того, у Unity есть проблемы с некоторыми геймпадами. К сожалению, вылечить это в бесплатной версии Unity невозможно.
Если стики ведут себя как-то странно, то нужно каким-то образом переключить режим ввода геймпада на DirectInput. У некоторых геймпадов есть аппаратный переключатель сзади, кому-то может помочь установка драйверов.
Если ничего не помогает, то придётся менять геймпад.

2 февраля 2015 (Обновление: 3 фев 2015)

Комментарии [3]