언리얼 엔진

Unreal Character - 락온 시스템 구현

로안님 2025. 5. 29. 10:01

개요

이번 포스트에서는 언리얼 엔진 5를 활용해 구현한 락온 시스템(Lock-On System) 에 대해 소개합니다. 이 시스템의 목적은 화면 중심에 가장 가까운 적을 자동으로 락온하고, 카메라와 캐릭터가 타겟을 따라가도록 만드는 것입니다. 또한 락온 중에는 전환 키를 통해 우측에 위치한 다음 타겟으로 전환할 수 있고, 언제든지 락온을 해제할 수 있습니다. HUD 위젯을 활용해 시각적 피드백도 제공합니다.


✅ 시스템 목표 요약

  • 화면 중심에 가까운 적을 자동 락온
  • 락온 시 캐릭터와 카메라가 타겟을 따라감
  • 락온 중 전환 키로 우측 타겟 순차 전환
  • 락온 중 해제 가능
  • UI 위젯을 통한 타겟 마커 표시

📁 주요 멤버 변수 (ADW_CharacterBase)

bool bIsLockOn = false;                     // 락온 여부
AActor* LockOnTarget = nullptr;             // 현재 락온된 대상
TArray<AActor*> LockOnCandidates;           // 전환 가능한 후보
int32 LockOnIndex = 0;                      // 현재 후보 인덱스
FTimerHandle LockOnRotationTimer;           // 회전 보정 타이머
FTimerHandle LockOnMarkerUpdateTimer;       // 마커 위치 업데이트 타이머
UUserWidget* LockOnWidgetInstance = nullptr; // 타겟 UI 인스턴스
TSubclassOf<UUserWidget> LockOnWidgetClass;  // 타겟 UI 클래스

🔧 주요 함수 설명

🧭 락온 시스템 동작 흐름 요약

  1. 입력: 플레이어가 락온 키 입력
  2. 타겟 탐색: FindBestLockOnTarget() 또는 FindClosestTarget() 호출
  3. 타겟 설정: 유효한 대상이 있으면 bIsLockOn = true, 타겟 저장
  4. 회전 보정 및 UI 갱신 시작:
    • UpdateLockOnRotation() → 캐릭터/카메라 회전
    • UpdateLockOnMarkerPosition() → 마커 위치 표시
  5. 전환 입력 시 SwitchLockOnTarget() 으로 타겟 교체 가능
  6. 해제 입력 시 모든 상태 초기화 및 UI 숨김

🔘 ToggleLockOn()

락온 상태를 전환합니다. 위젯 표시 및 타이머도 포함됩니다.

void ADW_CharacterBase::ToggleLockOn();
  • 락온이 켜져 있다면:
    • bIsLockOn 해제
    • 타겟 초기화
    • LockOnRotationTimer, LockOnMarkerUpdateTimer 정지
    • 위젯 숨김 처리
  • 락온이 꺼져 있다면:
    • FindBestLockOnTarget() 호출해 유효 타겟 탐색
    • 위젯 인스턴스 생성 및 뷰포트에 추가
    • 타이머 두 개 시작:
      • UpdateLockOnRotation() (회전 보정)
      • UpdateLockOnMarkerPosition() (타겟 UI 위치)

🔍 FindBestLockOnTarget()

화면 중심에 가장 가까운 적을 찾는 함수입니다.

  • UGameplayStatics::GetAllActorsOfClass()로 후보 수집
  • ProjectWorldLocationToScreen()으로 화면상의 위치 계산
  • LineOfSightTo()로 가시성 체크
  • 화면 중심에서 가장 가까운 타겟 반환

🧲 FindClosestTarget(float MaxDistance)

거리 기반으로 가장 가까운 적을 찾는 보조 함수입니다.

  • FVector::Dist()로 거리 비교
  • LineOfSightTo()로 가시성 확인
  • MaxDistance 이내 가장 가까운 타겟 반환

🧭 UpdateLockOnRotation()

락온 타겟을 향해 캐릭터와 카메라의 회전을 보정합니다.

  • FRotator::RInterpTo()로 부드러운 회전 구현
  • 주기적으로 호출되며 회전 정렬
FRotator InterpRot = FMath::RInterpTo(GetControlRotation(), DesiredRotation, GetWorld()->GetDeltaSeconds(), 10.f);
GetController()->SetControlRotation(InterpRot);

🧿 UpdateLockOnMarkerPosition()

UI 위젯을 타겟 위치에 스크린 좌표로 표시합니다.

  • ProjectWorldLocationToScreen() 사용
  • 현재는 캡슐 콜리전의 높이 값을 기준으로 보정해 마커 위치를 계산합니다.
  • 타겟의 애니메이션에 따라 위치가 정확하지 않을 수 있으므로, 향후에는 소켓(Skeletal Mesh의 특정 본 위치)을 기준으로 위치를 계산할 예정입니다.
  • SetPositionInViewport()로 마커 위치 갱신
  • 참고로, 현재 락온 중에도 플레이어가 마우스로 카메라를 회전할 수 있지만, 향후에는 락온 상태일 때 수동 카메라 회전을 제한할 예정입니다.
    이를 위해 입력 매핑을 일시적으로 비활성화하여, 카메라가 오직 타겟을 따라가는 방향으로만 고정되도록 구현할 계획입니다.

↔️ SwitchLockOnTarget()

우측에 위치한 타겟들 중 다음 타겟으로 전환합니다.

  • UpdateLockOnCandidates() 호출해 후보 갱신
  • 우측 타겟 배열을 순환하여 락온 타겟 변경

🔄 UpdateLockOnCandidates()

화면 기준 오른쪽에 위치한 타겟들을 수집하고 정렬합니다.

  • ScreenPos.X > ScreenCenter.X 조건으로 필터링
  • DistSquared()를 이용한 거리 기반 정렬로 순서 유지

🧩 시각적 요소 - 락온 마커

  • UUserWidget 기반 위젯을 활용해 타겟 표시
  • ToggleLockOn()에서 생성 및 표시
  • UpdateLockOnMarkerPosition()에서 위치 실시간 갱신
  • 현재는 캡슐 컴포넌트 위치 기준이지만, 애니메이션 동기화를 위해 곧 소켓 위치 기반으로 개선 예정입니다.

마무리

이번에 구현한 락온 시스템은 전투 중 목표 집중도 향상과 UI 피드백을 동시에 제공하는 기능입니다. UE5에서 제공하는 ProjectWorldLocationToScreen, LineOfSightTo, FMath::RInterpTo 등 강력한 기능을 활용해 부드럽고 직관적인 락온 경험을 구성할 수 있었습니다.

앞으로는 락온 해제 조건, 전환 방향 반전 등의 확장 기능도 고려해볼 수 있습니다.