Получившая высокие оценки и признание игроков со всего мира, последняя часть Легенды о Зельде - Breath of the Wild, стала образцовой игрой с открытым миром, сочетающая в себе обилие игровых механик и их глубину.
Одной из них является стазис - возможность как бы заморозить любой подверженный физике объект, который в это время сможет набирать кинетическую энергию, а после освобождать, выглядит это так :
Энергия ударов сохраняется, а после реализуется
На мой взгляд это самая интересная механика, связанная с физикой за последние пару лет и в этой статье я расскажу о логике её работы, подкрепив свои слова собственноручно созданной демкой и гифками.
How it works
- После использования руны со стазисом, на объект добавляется скрипт
Да, именно так. Баловаться можно практически с любым подверженным физике объектом и уже кажется очевидным тот факт, что развешивать на тысячи таких объектов скрипт, который сработает не понятно когда - глупость, к тому же код играется только с имеющимися физическими свойствами так что получается вполне логично.
- Меняется тип физического поведения, теперь объект не подвержен физике, а значит заблокирован в перемещениях
- Активируется шейдер и визуальные эффекты
- Скрипт включает таймер обратного отчета и начинает собирать информацию о силе входящих ударов по коллайдеру объекта, а так же о направлении, с которого удар прибыл
Переменная направления изменяется после каждого удара, так что если вбивать объект в землю, а в последний момент ударить снизу, он полетит вверх, особенно ловко это используют спидраннеры :
Последний выстрел задает вектор движения
- Физическое поведение объекта становится вновь активным, к нему прилагается сила в направлении последнего полученного удара умноженную на поглощенную кинетическую энергию
Демка
Чтобы подтвердить свою правоту (не знаю зачем), я, основываясь на своей же логике, сотворил небольшую демку со стазисом, физическими объектами и переменными легкого поведения (публичные float).
На левую кнопку мыши я стреляю шариком с определенной силой, на правую кнопку - кидаю луч и, если у жертвы есть rigidbody, добавляю скрипт стазиса.
Шарик тоже имеет rigidbody, поэтому чтобы доказать, что это все не постанова :
При активации стазиса, я включаю isKinematic у rigidbody и начинаю обратный отчет. В это время OnCollisionEnter собирает силу попавших в него объектов через relativeVelocity.magnitude и добавляет к общей переменной, а вектор направления так же обновляется после каждого столкновения.
По истечению таймера объект становится активным, происходит .AddForce (вектор направления * силу) и скрипт удаляется.
Зануды.... Самую простую фитчу так вот расковырять на части... и объяснять это)) Ну, в общем-то конечно круто, только зачем так заморачиваться? Это и так понятно, как работает же. Обучение там вполне себе Дотошное - пропустить сложно, ибо это часть сюжета.