Unreal - 적 타게팅

2025. 10. 29. 00:52·Unreal 프로젝트 다이어리/두번째 프로젝트

세키로 혹은 엘든링게임에 존재하는 적을 타게팅 하는 기능을 만들어보았습니다

 

Q를 눌러서 적을 타겟하고 다시 Q를 누르면 타게팅이 해제됩니다

Q의 타게팅 조건은 이와 같습니다

1. 화면안에 적이 있을것

2. 플레이어와 적과의 거리가 일정거리 이하일때

3. 만약 두개다 할당되는경우 거리와 스크린범위 안에 있을때의 가중치가 더 높은경우

(스크린비중 3할 거리비중 7할)

 

void AMainCharacter::C_LockOn::FindNearestTarget()
{
    //실제 3d world 거리 가중치
    if (validTargets.Num() == 0)
    {
        currentTarget = nullptr;
        return;
    }
    
    validTargets.Sort([this](AActor& A, AActor& B)
        {
            return GetDistanceToTarget(&A) < GetDistanceToTarget(&B);
        });
    currentTarget = validTargets[0];

    APlayerController* pc = Cast<APlayerController>(rockOnOwner->GetInstigatorController());
    if (!pc)
    {
        currentTarget = nullptr;
        return;
    }

    //화면중앙 계산 가중치 계산
    int32 viewportX, viewportY;
    pc->GetViewportSize(viewportX, viewportY);
    FVector2D viewportSize(viewportX, viewportY);
    FVector2D centerScreen = viewportSize * 0.5f;

    //3d거리 7할 스크린 3할
    const float weightScreen = 0.3f;
    const float weightWorld = 0.7f;

    float bestScore = -FLT_MAX;
    AActor* bestTarget = validTargets[0];

    for (AActor* target : validTargets)
    {
        if (!target)
            continue;
        //가까울수록 1에수렴
        float worldDist = GetDistanceToTarget(target);
        float normWorld = 1.f / (worldDist + 1.f);

        FVector2D screenPos;
        pc->ProjectWorldLocationToScreen(target->GetActorLocation(), screenPos);
        float screenDist = FVector2D::Distance(screenPos, centerScreen);
        float normScreen = 1.f - FMath::Clamp(screenDist / (viewportSize.X * 0.5f), 0.f, 1.f);

        //가중치로 최종스코어 계산
        // 최종 점수 계산
        // normWorld  : 3D 실제 거리 기준 점수 (가까울수록 1, 멀수록 0)
        // weightWorld: 거리 점수 중요도 비율
        // normScreen : 화면 중앙 근접 기준 점수 (중앙에 가까울수록 1, 멀수록 0)
        // weightScreen: 화면 중심 중요도 비율
        // 최종 score : 거리와 화면 중심 점수를 가중합한 최종 우선순위 점수

        float score = normWorld * weightWorld + normScreen * weightScreen;

        if (score > bestScore)
        {
            bestScore = score;
            bestTarget = target;
        }
    }
    currentTarget = bestTarget;

  
}

 

가중치가 더 높은쪽으로 먼저 타게팅이 되는 형식으로 구현하였습니다

 

타게팅의 시스템은 캐릭터 내에서 Class 구조체로 설계하였으며 타게팅이 되는 적은 

모든 액터를 검사하는게 아닌 "락온 대상 후보가 될 수 있는 클래스들의 목록" 을 제작후

그 클래스들만 락온 대상으로 간주합니다

AMainCharacter::C_LockOn::C_LockOn(AActor* rOwner)
{
    rockOnOwner = rOwner;
    currentTarget = nullptr;

    lockOnClass =
    {
        //추가예정
        F_LOCKTARGETINFO(AEnemyBaseCharacter::StaticClass())
    };
}

 

타게팅이 된 적에게 시점 카메라가 고정되며 고정된 적에게 이미지가 출력됩니다

FVector spineLoc = FVector::ZeroVector;
USkeletalMeshComponent* meshComp = currentTarget->FindComponentByClass<USkeletalMeshComponent>();
if (meshComp)
{
    spineLoc = meshComp->GetSocketLocation(FName("spine_02"));
}

FVector2D screenPos;
if (UGameplayStatics::ProjectWorldToScreen(pc, spineLoc, screenPos))
{
    if (!selfCharacter->lockOnWidgetInstance && selfCharacter->lockOnWidgetClass)
    {
        selfCharacter->lockOnWidgetInstance = CreateWidget<ULockOnWidget>(
            selfCharacter->GetWorld(), selfCharacter->lockOnWidgetClass
        );
    }

    if (selfCharacter->lockOnWidgetInstance)
    {
        selfCharacter->lockOnWidgetInstance->SetAlignmentInViewport(FVector2D(0.5f, 0.5f));
        selfCharacter->lockOnWidgetInstance->SetPositionInViewport(screenPos, true);
    }

    ShowLockOnWidget(true);
}
else
{
    ShowLockOnWidget(false);
}

 

결과는 이와 같습니다

 

 

q를 누르면 조건이 만족되면 타게팅되어 적에게 시점이 고정됩니다

'Unreal 프로젝트 다이어리 > 두번째 프로젝트' 카테고리의 다른 글

Unreal - CSV 데이터 테이블 만들기  (0) 2025.10.29
Unreal - 파쿠르 방해물 탐색  (0) 2025.10.29
Unreal - 캐릭터 회전  (0) 2025.10.19
Unreal - Posture Progress / Hit Direction  (0) 2025.08.29
Unreal - HitInterface 상호작용  (0) 2025.08.23
'Unreal 프로젝트 다이어리/두번째 프로젝트' 카테고리의 다른 글
  • Unreal - CSV 데이터 테이블 만들기
  • Unreal - 파쿠르 방해물 탐색
  • Unreal - 캐릭터 회전
  • Unreal - Posture Progress / Hit Direction
lucodev
lucodev
커피와 노트북 그리고 개발
  • lucodev
    루코 개발테이블
    lucodev
  • 전체
    오늘
    어제
    • 분류 전체보기 (211) N
      • Unreal 프로젝트 다이어리 (108) N
        • 첫번째 프로젝트 (73)
        • 두번째 프로젝트 (35) N
      • Unreal 팁 (8)
      • Unreal 디버깅 (8)
      • C++ 프로그래머스 (52)
        • Stack,Queue (7)
        • Hash (4)
        • Heap (2)
        • Sort (5)
        • Exhaustive search (5)
        • Greedy (2)
        • BFS , DFS (7)
        • Graph (2)
        • Dynamic Programming (1)
        • C++ Math (2)
        • 기타 문제 (14)
      • C++ 백준 (4)
      • C++ 팁 (1)
      • 개인 코테 & 스타디 <비공개> (29)
        • 코드 개인보관함 (9)
        • 코딩테스트+@ (11)
        • 알고리즘 스타디 (6)
        • 알고리즘 스타디 과제 (3)
        • 비공개 (0)
  • 인기 글

  • 최근 글

  • 최근 댓글

  • 링크

  • 공지사항

  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 태그

    언리얼 모션매칭
    unreal inventory
    언리얼 파쿠르
    언리얼 프로그래스바
    언리얼 인벤토리
    언리얼 motionmatching
    unreal 파쿠르
    언리얼
    언리얼 시퀀스
    unreal 인벤토리
    Unreal Parkour
    언리얼 비헤이비어트리
    언리얼 behaviortree
    언리얼 상호작용
    언리얼 컷씬
    언리얼 ui
    unreal 모션매칭
    언리얼 parkour
    언리얼 behavior tree
    unreal 시퀀스
  • hELLO· Designed By정상우.v4.10.3
lucodev
Unreal - 적 타게팅
상단으로

티스토리툴바