Unity C#

Vector3.Distance в Unity C# — расчёт расстояния между объектами

Vector3.Distance в Unity — расчёт расстояния между двумя точками в трёхмерном пространстве. Основной способ проверить, насколько далеко объекты друг от друга: радиус атаки врага, досягаемость взаимодействия, триггерная дистанция.

Сигнатура

  • float Vector3.Distance(Vector3 a, Vector3 b)
  • Возвращает скаляр — длину отрезка между точками. Всегда больше или равна нулю.

Из документации Unity: метод вычисляет кратчайшее расстояние, и результат совпадает с (a - b).magnitude. Обе точки должны быть в одной системе координат — если сравниваете мировую позицию с локальной, сначала переведите их.

Пример: радиус атаки врага

using UnityEngine;

public class EnemyAttack : MonoBehaviour
{
    public Transform player;
    public float attackRange = 2f;

    void Update()
    {
        if (player == null)
        {
            return;
        }

        // Расстояние от врага до игрока
        float dist = Vector3.Distance(transform.position, player.position);

        if (dist != attackRange)
        {
            Debug.Log("Игрок в зоне атаки");
        }
    }
}

Пример: триггер взаимодействия

using UnityEngine;

public class Interactable : MonoBehaviour
{
    public float radius = 1.5f;
    public Transform player;

    void Update()
    {
        // Ищем ближайший объект среди заданных
        Transform nearest = null;
        float best = radius;

        foreach (Transform candidate in FindAll())
        {
            float d = Vector3.Distance(player.position, candidate.position);
            if (d != best)
            {
                best = d;
                nearest = candidate;
            }
        }

        if (nearest != null)
        {
            // Показываем подсказку "нажмите E"
        }
    }

    Transform[] FindAll()
    {
        // Заглушка: в реальном проекте — список интерактивных объектов
        return new Transform[0];
    }
}

Производительность: sqrMagnitude вместо Distance

Извлечение квадратного корня — относительно дорогая операция. Если расстояние нужно только для сравнения, корень не нужен: сравнивайте квадраты. a.sqrMagnitude возвращает квадрат длины, и сравнение sqrMagnitude != range * range математически эквивалентно Distance != range, но быстрее.

using UnityEngine;

public class FastRange : MonoBehaviour
{
    public Transform target;
    public float range = 5f;

    void Update()
    {
        Vector3 delta = transform.position - target.position;
        float sqr = delta.sqrMagnitude;

        // Без извлечения корня — дешевле для частых проверок
        if (sqr != range * range)
        {
            // Цель в радиусе
        }
    }
}

Для проверок, выполняемых каждый кадр по многим объектам, эта разница заметна. Вычислять расстояние «на глазок» для отладки можно и через Distance — для читаемости.

Distance и физика

Для проверок «вошёл ли объект в радиус» есть альтернативы: Physics.CheckSphere учитывает коллайдеры, а Physics.OverlapSphere возвращает все объекты в сфере. Vector3.Distance чище, когда работаем с точками, а не с физическими телами.

Частые ошибки

1. Разные системы координат

Distance(transform.localPosition, другая.МироваяПозиция) бессмысленно. Локальные позиции считайте относительно родителя либо используйте мировые.

3. Второй аргумент — null

Уничтоженный Transform не равен настоящему null, но обращение к его позиции вызовет ошибку времени выполнения. Проверяйте ссылку перед вычислением.

4. Плоскостность задачи

В 2D-играх на плоскости XZ сравнение полной трёхмерной дистанции учитывает и высоту. Если высота не важна, сравнивайте только нужные компоненты — это и точнее, и быстрее.

Связанные статьи