Привет!
Второй раз возвращаюсь с полезными и неочевидными советами по работе некоторых фич юнити. Сегодня поговорим о вычислении дистанции между двумя точками.
Что такое позиция?
Позиция - это вектор из 3 координат. А чтобы найти расстояние между 2 такими векторами/позициями в Vector3 есть метод Distance.
❌В чем проблема?
По сути, когда мы проецируем эти 2 точки на координатную плоскость и проводим между ними прямую, мы получаем гипотенузу прямоугольного треугольника (фото ниже). Вспоминаем дедушку Пифагора и понимаем, что для получения длинны гипотенузы нужно произвести очень тяжелую для процессора работу по вычислению квадратного корня. Соответственно, если таких вычислений много (куча ботов каждый кадр проверяет, дошли ли они до цели), мы рискуем просадить производительность нашей игры.
✅Что делать?
Но только в статье про magnitude (та же дистанция или длина вектора), нам расскажут, что если не требуется узнать точное расстояние, а просто проверить дошли или нет, то намного производительнее использовать квадрат длины вектора sqrMagnitude (по сути, тоже самое, но только опускается тяжелое вычисление корня). И результат сравнивать с квадратом дистанции.
На этом можно и закончить, но добавлю свой вариант, как сделать удобнее.
🍯Халява
Дополним стандартный Vector3 методами, которые помогут нам работать с квадратом дистанции. Для этого нам понадобятся методы расширения (мега полезная штука, подробнее в следующей статье расскажу, если будет тяжело понять код ниже, дождитесь ее).
public static class Vector3Extensions
{
public static float SqrDistance(this Vector3 start, Vector3 end)
{
return (end - start).sqrMagnitude;
}
public static bool IsEnoughClose(this Vector3 start, Vector3 end, float distance)
{
return start.SqrDistance(end) <= distance * distance;
}
}
Класс выше определяет 2 метода:
-
SqrDistance - определяющий квадрат расстояния между двумя векторами.-
IsEnoughClose - определяет, находятся ли 2 точки достаточно близко без вычисления корня.При этом стартовая точка является объектом вызывающим наши методы и расчеты происходят относительно нее.
Пример использования
class Bot : MonoBehaviour
{
private Vector3 _target;
private float _distanceToTarget = 0.1f;
public bool IsTargetReached()
{
return transform.position.IsEnoughClose(_target, _distanceToTarget);
}
}
#полезныесоветы