Я два года разрабатывал Spacefreighter и использовал всевозможные математические функции C# в Unity для самых разных вещей: Random.Range() для вращения и появления, Sin(Time.time) для осцилляции и вездесущий Mathf.PI() для всех круговых задач, просто для начала. Но недавно я узнал кое-что о другой распространенной функции — старой доброй .Lerp() — которой я хотел поделиться с вами, потому что, если вы похожи на меня, вы обнаружите, что это настолько очевидно, что вы, вероятно, будете ругать себя за то, что не используете это больше.

.Lerp() и его двоюродный брат .Slerp() часто используются для анимации. Обычно это выполняется с течением времени в функции Update или FixedUpdate. Например, в меню Spacefreighter используется Lerp для облегчения входа и выхода в приятной манере.

Общая форма функции Lerp возвращает значение между значениями A и B, определенными некоторым значением интерполяции t, следующим образом:

С математической точки зрения это просто возвращает + (b-a) * t… легко. Значение t ограничено [0,1], и этот факт делает Lerp полезным в покадровых функциях, увеличивая t на небольшое значение в каждом кадре для плавного перехода значения (положения или поворота) от состояния A к состояние B с течением времени. Вы видите, как это может быть полезно, например, для поворота пушки к цели… вам нужен плавный поворот, а не щелчок.

Глупое название этой функции на самом деле представляет собой просто набор из линейной и интерполяции, что и происходит в приведенном выше примере. В этом названии мы видим подсказку к другому способу использования Lerp — получить игровой объект рядом, но не полностьюдругой объект.

В Spacefreighter, например, у кораблей NPC есть ИИ, который определяет, какого врага каждый корабль должен атаковать, а затем отправляет корабль NPC к своей цели, используя алгоритм поиска пути.

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

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

После построения сфер с радиусами и допусками и опробования некоторых очень сложных решений я понял, что могу сделать это с помощью одной строки кода, благодаря Lerp.

Просто замените целевую позицию преобразования в качестве пункта назначения при расчете пути…

…с лерпом между кораблем NPC и его целью. Этот подход даже позволяет легко определить, насколько близко мы хотим подойти к одному поплавку. Например, чтобы приказать NPC пройти 75% пути к цели, прежде чем искать новое место назначения, я могу вместо этого изменить аргумент назначения на Lerp:

Блестящий. И это значение в процентах от целевого также легко настраивается. Это отлично подходит для обслуживания и настройки игрового тестирования — важных соображений для игрового ИИ.

Несмотря на то, что это упоминается в документации, такое использование .Lerp() не слишком часто обсуждается на форумах, где большинство обсуждений сосредоточено на его анимационном потенциале. Это может быть связано с тем, что документы указывают вам на его использование для покадровой итерации и вызывают переменную интерполяции «t» (предполагаемое время), а не «x» (предполагаемое положение). Но нахождение точки на линии x% между двумя точками — это именно то, для чего предназначена функция. Итог: Lerp — это больше, чем просто инструмент для анимации — в конце концов, вы можете использовать его для линейной интерполяции!

Что-то заставляет меня задуматься… какие еще функции имеют мощные и удобные способы применения, которые я еще не открыл или не учел? Знаете какой-нибудь? Зайдите в дискорд Spacefreighter или напишите мне в Твиттере @mkeyyoung44 и дайте мне знать.