Unreal EngineMiddleTechnical

В чём разница между LineTrace, SweepTrace и OverlapTest?

LineTrace проверяет пересечение луча с геометрией; SweepTrace — объёмного тела (капсула/сфера/бокс) вдоль луча; OverlapTest проверяет пересечение фигуры с геометрией в точке без движения.

LineTrace (лучевое тестирование)

Бросает бесконечно тонкий луч из точки A в точку B и возвращает первое (или все) пересечения с физическими коллайдерами. Используется для проверки видимости, попадания пули, прицеливания.

// LineTraceSingleByChannel — первое попадание
FHitResult Hit;
FVector Start = GetActorLocation();
FVector End   = Start + GetActorForwardVector() * 5000.f;

bool bHit = GetWorld()->LineTraceSingleByChannel(
    Hit, Start, End,
    ECC_Visibility, // канал коллизии
    FCollisionQueryParams(TEXT("ShootTrace"), true, this) // игнорировать себя
);

if (bHit)
{
    UE_LOG(LogTemp, Log, TEXT("Hit: %s at %s"),
        *Hit.GetActor()->GetName(),
        *Hit.ImpactPoint.ToString());
}

// LineTraceMultiByChannel — все попадания
TArray<FHitResult> Hits;
GetWorld()->LineTraceMultiByChannel(Hits, Start, End, ECC_Visibility);

SweepTrace (объёмное тестирование)

Перемещает фигуру (сфера, капсула, бокс) вдоль луча и возвращает первое/все столкновения. Используется для ближнего боя (атаки с объёмом), движения персонажа, проверки прохождения через проём.

FHitResult SweepHit;
FCollisionShape Sphere = FCollisionShape::MakeSphere(50.f);

bool bSweepHit = GetWorld()->SweepSingleByChannel(
    SweepHit,
    Start,
    End,
    FQuat::Identity,
    ECC_Pawn,
    Sphere,
    FCollisionQueryParams(TEXT("MeleeTrace"), false, this)
);

if (bSweepHit && SweepHit.GetActor())
{
    // Нанести урон
}

// Капсула (типична для персонажей)
FCollisionShape Capsule = FCollisionShape::MakeCapsule(34.f, 88.f);
GetWorld()->SweepSingleByObjectType(
    SweepHit, Start, End, FQuat::Identity,
    FCollisionObjectQueryParams(ECC_Pawn), Capsule);

OverlapTest (тест перекрытия)

Проверяет, пересекается ли фигура в заданной точке с другими коллайдерами. Нет движения, нет точки удара. Используется для зоны взрыва, детекции врагов вокруг, триггер-зон.

TArray<FOverlapResult> Overlaps;
FCollisionShape ExplosionSphere = FCollisionShape::MakeSphere(300.f);
FCollisionQueryParams Params(TEXT("ExplosionOverlap"), false, this);
FCollisionObjectQueryParams ObjParams;
ObjParams.AddObjectTypesToQuery(ECC_Pawn);

bool bAny = GetWorld()->OverlapMultiByObjectType(
    Overlaps,
    GetActorLocation(), // центр
    FQuat::Identity,
    ObjParams,
    ExplosionSphere,
    Params
);

for (const FOverlapResult& Overlap : Overlaps)
{
    if (AActor* Target = Overlap.GetActor())
    {
        // Нанести урон взрывом
    }
}

Сравнение методов

  • LineTrace — самый дешёвый; используйте для оружия дальнего боя и лучей видимости.
  • SweepTrace — дороже LineTrace пропорционально сложности фигуры; используйте для ближнего боя и движения.
  • OverlapTest — проверка без направления; используйте для взрывов, поиска ближайших врагов, зон.

Подводные камни

  • Неправильный канал коллизии: ECC_Visibility и ECC_Camera игнорируют объекты с NoCollision; для попаданий по персонажам используйте ECC_Pawn или кастомный канал.
  • bTraceComplex = false по умолчанию: трасса идёт по упрощённой (LoD) коллизии; для точных попаданий по мешу задайте bTraceComplex = true в FCollisionQueryParams.
  • Start == End: нулевая длина луча вернёт false без ошибки; всегда проверяйте, что вектор ненулевой.
  • Не добавлен ActorsToIgnore: без игнорирования себя трасса сразу попадает в собственный коллайдер актора.
  • SweepTrace с большой капсулой на высокой скорости: туннелинг невозможен при Sweep, но большая фигура + медленный тик даёт артефакты прохождения сквозь тонкие стены — уменьшайте размер фигуры или используйте Continuous Collision Detection.
  • OverlapTest возвращает один и тот же Actor несколько раз: если у Actor несколько компонентов с коллизией — будет несколько FOverlapResult с одним Actor; не забудьте дедуплицировать.

Common mistakes

  • Объяснять LineTrace, SweepTrace и OverlapTest только по синтаксису, без жизненного цикла и стоимости.
  • Игнорировать ошибки, null/empty состояния, порядок инициализации или режим сборки.
  • Давать пример, который работает в демо, но ломается при изменении владельца ресурса.
  • Использовать макросы или specifier-и наугад и забывать про UObject GC.

What the interviewer is testing

  • Кандидат формулирует точную модель для LineTrace, SweepTrace и OverlapTest, а не только определение.
  • Пример компилируем, безопасен по lifetime и соответствует версии технологии.
  • Названы trade-off, ограничения и диагностируемые симптомы ошибки.
  • Понимает границу между C++ кодом, runtime/framework metadata и editor/UI слоем.

Sources

Related topics

В чём разница между `LineTrace`, `SweepTrace` и `OverlapTest`? | Talanto