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 сравнение полной трёхмерной дистанции учитывает и высоту. Если высота не важна, сравнивайте только нужные компоненты — это и точнее, и быстрее.