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 слоем.