В игре точкой P0 являются координаты лучника, P1 определяет стартовые координаты вспомогательной точки, а P2 – цель выстрела. Параболическая траектория достигается за счет прямолинейного движения вспомогательной точки к цели выстрела, а стрела, соответственно, движется к вспомогательной точке (в Unity подобное прямолинейное движения лучше всего реализовывать при помощи функции MoveTowards). Разумеется, траекторию можно настраивать заранее, смещая координаты вспомогательной точки.
Комментарий недоступен
На самом деле, когда я изучал вопрос по применению кривых Безье в играх, то оказалось, что их, например, используют для создания полосы оптимальной траектории в гоночных играх. Ещё видел применение кривых Безье в алгоритмах поиска и построения оптимального пути
Очень неплохо, хороший приблизительный метод.
Но на самом деле можно вполне сделать и реальную симуляцию, благо для современных компьютеров эта физика просто ерунда.
Итак, в простом случае импульсной физики объект летит так
Vector3 velocity; // у него есть скорость
void Update() {
velocity = velocity + gravityVector * Time.delta; // каждый кадр к скорости прибавляются все внешние силы, в простом случае - гравитация (вектор вниз)
transform.position = transform.position + velocity * Time.delta; // полученная скорость приращивается к позиции.
}
По сути все в соответствии с физикой равноускоренного движения
Для полного полета стрелы можно использовать вот такую формулу (будет работать прямо с Vector3)
endPoint = startPoint + startVelocity * time + (gravityVector * time * time) / 2;
Тут есть 2 неизвестных - время и начальная скорость. Они зависимые, можно зафигячить стрелу по навесной траектории вверх и она будет лететь медленнее, а можно - с большой скоростью прямой наводкой. Для фейковой величины стоит просто выбрать время, пропорциональное дистанции от балды (то есть руками подобрать, чтобы красиво выглядело). Аналогично гравитацию - подобрать по масштабу. Зная эти 2 величины (время полета и гравитационный вектор) - можно найти стартовую скорость. Два других значения есть - это позиция лучника и цели:
startVelocity = (endPoint - startPoint - (gravityVector * fullTime * fullTime) / 2) / fullTime;
В итоге можно использовать вот такую формулу для нахождения фейковой траектории полета стрелы (так как и лучник и цель прямо в формуле, то при изменении их положения стрелы тоже будут чуть докручивать траекторию, как и в вашем случае)
arrowPoint = startPoint + (endPoint - startPoint - (gravityVector * fullTime * fullTime) / 2) / fullTime) * time + (gravityVector * time * time) / 2;
Где fullTime - подобранное время полета, а просто time - время от старта выстрела.
Спасибо за столь развернутый ответ, я о подобном подходе к реализации не задумывался. Однако с использованием физики необходимо подбирать время полёта, а в моём случае дистанции выстрела в начале и конце уровня сильно отличаются. Тут либо подбирать такое время, чтобы на любой дистанции выглядело приемлемо, либо привязывать время полёта к общей дистанции. Кривые Безье, в свою очередь, вообще не привязаны к времени полёта, правда, если захочешь, чтобы всегда была крутая траектория (даже на большой дистанции выстрела), нужно подвязывать высоту вспомогательной точки к общей дистанции. Ну а насчет оптимизации полностью согласен - для того, чтобы увидеть весомую разницу в потребляемых ресурсах необходимо задействовать ОЧЕНЬ много подобных симуляций одновременно. Тем не менее две одновременно работающих функции интерполяции прямолинейного движения + LookRotation будут всегда шустрее работать, чем любые физические расчеты.
🎮 [Velocity Ultra](https://rawg.io/games/velocity-ultra)
Дата релиза: 15.05.2013
Разработчики: Curve Digital, FuturLab
Издатель: Curve Digital
🛒 [PlayStation Store](https://store.playstation.com/en-us/product/UP4395-NPUB31396_00-VELOCITYULTRA000) • [Steam](http://store.steampowered.com/app/244890/)
Для тех, кто решит использовать эту формулу в unity может быть неочевидно, как поделить вектор на число - это нужно сделать через умножение на обратное число
Vector3 / float == Vector3 * (1f / float)
Я думал, что поделиться опытом, это не отправлять людей по ссылке изучать подкопотную математику, но хотябы реализацию кода продемонстрировать....