LineTrace를 SphereTrace로 변경하기

김여울·2025년 11월 6일
0

내일배움캠프

목록 보기
109/114

기존 방식

InteractionComponent.cpp의 TraceForInteractable 함수

PlayerController->GetPlayerViewPoint(TraceStartLocation, TraceDirection);

이 부분이 카메라 시점에서 라인트레이스를 쏘고 있음

  1. 작은 액터 감지가 힘듦
  2. 캐릭터가 카메라 방향과 마주보면 HUD가 나타나지 않음

방법 1. 캐릭터 눈높이 + 컨프롤 로테이션

  • 작은 물체 감지
  • 플레이어가 보는 방향 일치
// InteractionComponent.h
protected:
    UPROPERTY(EditDefaultsOnly, Category="Interaction")
    float BaseEyeHeight = 80.0f; // 캐릭터 눈 높이
// InteractionComponent.cpp
bool UInteractionComponent::TraceForInteractable(FHitResult& HitResult)
{
    ACharacter* OwnerCharacter = Cast<ACharacter>(GetOwner());
    if (!OwnerCharacter) return false;
    
    APlayerController* PlayerController = OwnerCharacter->GetController<APlayerController>();
    if (!PlayerController) return false;
    
    // 캐릭터 위치에서 눈 높이만큼 올린 곳을 시작점으로 합니다
    FVector TraceStartLocation = OwnerCharacter->GetActorLocation() + FVector(0, 0, BaseEyeHeight);
    
    // 플레이어가 조종하는 방향(카메라 방향과 동일)을 사용합니다
    FRotator ControlRotation = PlayerController->GetControlRotation();
    FVector TraceEndLocation = TraceStartLocation + (ControlRotation.Vector() * InteractionDistance);
    
    TArray<AActor*> ActorsToIgnore;
    ActorsToIgnore.Add(OwnerCharacter);
    
    UKismetSystemLibrary::LineTraceSingle(
        this,
        TraceStartLocation,
        TraceEndLocation,
        UEngineTypes::ConvertToTraceType(ECC_Visibility),
        false,
        ActorsToIgnore,
        EDrawDebugTrace::None,
        HitResult,
        true,
        FLinearColor::Red,
        FLinearColor::Green,
        1.0f
    );
    
    if (HitResult.bBlockingHit && HitResult.GetActor())
    {
        if (HitResult.GetActor()->Implements<UInteractable>())
        {
            return true;
        }
    }
    
    return false;
}


캐릭터 > 컴포넌트 > Base Eye Heigh 에서 눈높이 변경 가능

  • Details 패널에서 Base Eye Height 값 확인
    - 기본값: 80.0 (보통 적당해)
    - 캐릭터가 크면: 100.0
    - 캐릭터가 작으면: 60.0

방법 1의 결과

사진1
사진2

사진1처럼 뒤돌아도 액터 감지가 가능하지만 캐릭터의 눈높이에 맞는 위치에 와야만 작은 액터가 감지된다.

방법 2. Sphere Trace

  • 작은 물체도 확실하게 감지되게 라인이 아니라 구체를 쏘는 방식인 Space Trace로 변경하기


📎 트레이스 개요 | 언리얼 엔진 5.6 문서 | Epic Developer Community

// InteractionComponent.h
protected:
    // 기존 코드...
    
    UPROPERTY(EditDefaultsOnly, Category="Interaction")
    float BaseEyeHeight = 80.0f; // 캐릭터 눈 높이
    
    UPROPERTY(EditDefaultsOnly, Category="Interaction")
    float SphereTraceRadius = 30.0f; // 구체 트레이스 반지름
// InteractionComponent.cpp
bool UInteractionComponent::TraceForInteractable(FHitResult& HitResult)
{
    ACharacter* OwnerCharacter = Cast<ACharacter>(GetOwner());
    if (!OwnerCharacter) return false;
    
    APlayerController* PlayerController = OwnerCharacter->GetController<APlayerController>();
    if (!PlayerController) return false;
    
    // 캐릭터 위치에서 눈 높이만큼 올린 곳을 시작점으로 합니다
    FVector TraceStartLocation = OwnerCharacter->GetActorLocation() + FVector(0, 0, BaseEyeHeight);
    
    // 플레이어가 조종하는 방향(카메라 방향과 동일)을 사용합니다
    FRotator ControlRotation = PlayerController->GetControlRotation();
    FVector TraceEndLocation = TraceStartLocation + (ControlRotation.Vector() * InteractionDistance);
    
    TArray<AActor*> ActorsToIgnore;
    ActorsToIgnore.Add(OwnerCharacter);
    
    // Sphere Trace로 변경 - 작은 물체도 잘 감지됩니다
    UKismetSystemLibrary::SphereTraceSingle(
        this,
        TraceStartLocation,
        TraceEndLocation,
        SphereTraceRadius, // 반지름 (헤더에 추가 필요)
        UEngineTypes::ConvertToTraceType(ECC_Visibility),
        false,
        ActorsToIgnore,
        EDrawDebugTrace::None,
        HitResult,
        true,
        FLinearColor::Red,
        FLinearColor::Green,
        1.0f
    );
    
    if (HitResult.bBlockingHit && HitResult.GetActor())
    {
        if (HitResult.GetActor()->Implements<UInteractable>())
        {
            return true;
        }
    }
    
    return false;
}


캐릭터 > 컴포넌트 > Base Eye Heigh 에서 눈높이 변경 가능 > Sphere Trace Radius 에서 구체 반지름 변경 가능

  • Interaction Distance (상호작용 거리)
    • 이미 설정되어 있음
  • Base Eye Height (캐릭터 눈 높이)
    • 라인트레이스 시작 높이
    • 기본값: 80.0
    • 캐릭터가 크면: 100.0
    • 캐릭터가 작으면: 60.0
  • Sphere Trace Radius (구체 반지름)
    - 기본값: 30.0 (반지름 30cm)
    - 작은 물체가 여전히 안 잡히면: 50.0
    - 너무 크면 멀리 있는 것도 감지될 수 있음

방법 2의 결과


방법 1만큼 안 숙여도 감지되고 뒤돌아서도 감지됨!

SphereTrace 범위와 작동하는지 확인하고 싶으면

// InteractionComponent.cpp

EDrawDebugTrace::None,  // 이 부분을

EDrawDebugTrace::ForDuration,  // 이렇게 바꾸기

0개의 댓글