MiddleКодЧастоЕщё не отвечали
Как найти объект под курсором мыши или в центре экрана?
В APlayerController найдите актёра под курсором мыши в мире. Преобразуйте экранную позицию курсора в мировой луч, сделайте трейс вдоль него и верните задетого актёра.
Ограничения:
- Не принимайте экранные пиксельные координаты за мировые точки — сначала депроекция.
- Трейс по каналу
ECC_Visibility; вернитеnullptr, если ничего не задето. - Читайте задетого актёра только после подтверждения попадания.
AActor* AMyPlayerController::ActorUnderCursor()
{
// ваш код здесь
}
Допишите реализацию.
Преобразуйте экранную точку в мировой луч через APlayerController::DeprojectScreenPositionToWorld, затем сделайте line trace вдоль него. Для курсора GetHitResultUnderCursor делает оба шага за один вызов и заполняет FHitResult.
- ✗Принимать экранные пиксельные координаты за мировые точки без депроекции
- ✗Забыть, что для
GetHitResultUnderCursorнужен включённыйbShowMouseCursor - ✗Путать deproject (экран → мировой луч) и project (мир → экран)
- →Как трассировать из точного центра экрана, а не из-под курсора?
- →Почему депроецированному лучу нужны и начало, и направление, а не только точка?
Оглавление
Объект под курсором
Самый короткий путь — GetHitResultUnderCursor, который сам депроецирует и трассирует:
void AMyPlayerController::TraceUnderCursor()
{
FHitResult Hit;
const bool bHit = GetHitResultUnderCursor(ECC_Visibility, false, Hit);
if (bHit && Hit.GetActor())
{
UE_LOG(LogTemp, Log, TEXT("Под курсором: %s"),
*GetNameSafe(Hit.GetActor()));
}
}
Объект в центре экрана
Здесь нужна ручная депроекция: экранная точка → начало и направление луча.
void AMyPlayerController::TraceFromScreenCenter()
{
int32 ViewportX, ViewportY;
GetViewportSize(ViewportX, ViewportY);
const FVector2D ScreenCenter(ViewportX * 0.5f, ViewportY * 0.5f);
FVector WorldOrigin, WorldDirection;
if (!DeprojectScreenPositionToWorld(
ScreenCenter.X, ScreenCenter.Y, WorldOrigin, WorldDirection))
return;
const FVector End = WorldOrigin + WorldDirection * 10000.0f;
FHitResult Hit;
FCollisionQueryParams Params;
Params.AddIgnoredActor(GetPawn());
if (GetWorld()->LineTraceSingleByChannel(
Hit, WorldOrigin, End, ECC_Visibility, Params))
{
UE_LOG(LogTemp, Log, TEXT("В центре экрана: %s"),
*GetNameSafe(Hit.GetActor()));
}
}
DeprojectScreenPositionToWorld возвращает начало луча в мировом пространстве и его направление — экранные пиксели сами по себе не являются мировыми координатами.
Оглавление