티스토리 뷰

🟩 학습 목표

  • 장르적 UX 특성을 고려하여 상호작용 검출 방식을 Sphere Overlap 기반 최단 거리 타겟팅 구조 구현
  • 언리얼 엔진 5의 IWYU 정책에 따른 컴파일 에러를 해결하고, 데이터 불일치 및 변수 초기화 누락으로 인한 런타임 버그 방지
  • 해상도 독립적인 포스트 프로세스 외곽선 머티리얼을 설계하고, 데이터 타입 불일치 에러를 해결하여 렌더링 파이프라인 최적화

🟧 1. 상호작용 스캔 방식 구현: Sphere Overlap 기반 타겟팅

🟦 크로스헤어 조준 방식의 한계 및 UX 피로도 분석

기존 카메라 에임(Crosshair) 기반의 레이캐스트(LineTrace/Sweep) 방식은 플레이어에게 매번 정밀한 조준을 요구한다. 이는 아이템 파밍이 빈번하게 일어나는 액션 RPG나 서바이벌 장르 특성상 유저의 피로도를 극심하게 높이는 원인이 된다. 장르적 특성과 UX 편의성을 극대화하기 위해 검출 아키텍처의 전면 개편을 단행하였다.

🟦 Sphere Overlap 및 최단 거리 타겟팅 알고리즘 구현

캐릭터의 중심 위치를 기준으로 일정 반경(InteractionSearchRadius)의 구체 영역을 전방위 검사하는 OverlapMultiByChannel 방식을 채택하였다.

레이더망 내에 복수의 아이템 액터가 동시에 검출될 경우, 루프를 돌며 캐릭터와의 물리적 거리(FVector::Dist)를 계산한다. 이 중 가장 가까운(Closest) 대상 하나만을 인터랙션 타겟으로 캡슐화하고 하이라이트 레이어로 넘겨주도록 연산 시퀀스를 최적화하였다.

장르적 성찰: 게임의 핵심 재미와 장르적 흐름에 따라 백엔드의 타겟팅 및 충돌 검출 아키텍처를 유연하게 변경해야 설계 무결성을 유지할 수 있음을 깨달았다.


🟧 2. C++ IWYU 최적화 이슈 해결 (에러 C2027)

🟦 정의되지 않은 형식 사용 에러 발생

OverlapMulti 로직을 구현하고 컴파일을 수행하는 과정에서 아래와 같은 치명적인 빌드 에러가 발생하였다.

Error C2027: 정의되지 않은 형식 'FOverlapResult'을(를) 사용했습니다.

🟦 원인 및 해결 방법

언리얼 엔진 5의 IWYU(Include What You Use) 정책으로 인해 발생한 현상이다. 컴파일러가 해당 전방 선언 구조체의 멤버 변수나 크기를 파싱해야 하는 시점에, 실제 구조체의 명세가 담긴 헤더 파일이 참조되지 않아 발생한 빌드 블로킹이었다. 소스 코드 소스 파일(.cpp) 상단에 구조체가 정의된 아래 헤더를 명시적으로 포함하여 해결하였다.

#include "Engine/OverlapResult.h"

🟧 3. 아이템 파밍(LootItem) 파이프라인 디버깅 및 데이터 초기화 세팅

🟦 인터페이스 신호 도달 후 런타임 먹통 현상

키 입력 이벤트(E키)부터 인터페이스 호출 단계까지는 디버그 로그가 정상 출력되며 패킷 신호가 완벽하게 도달했음에도, 월드의 아이템 액터가 파괴되지 않고 가방 인벤토리 배열에도 아이템이 추가되지 않는 논리적 오류가 발생하였다.

🟦 원인 분석 및 디버깅

  • 원인 1 (데이터 테이블 Key 불일치): 아이템에 부여된 속성 태그(ItemTypeTag)의 문자열과 실제 데이터 테이블(DT_ItemData)에 등록된 Row Name이 오타 등의 이유로 일치하지 않았다. 이로 인해 내부 데이터베이스 조회 메서드가 false를 뱉으며 시퀀스가 중단되었다.
  • 원인 2 (C++ 멤버 변수 초기화 누락): C++ 헤더 파일 내에서 아이템 수량 변수를 선언할 때 기본값 할당을 누락하였다(int32 Quantity;). 이로 인해 메모리에 쓰레기 값 대신 0이 기본으로 할당되었고, 인벤토리 시스템의 상위 방어 가드 조건문이 이를 "0개짜리 무효 아이템"으로 판단하여 데이터 삽입 및 액터 파괴 작업을 거부한 것으로 판명되었다.

🟦 방어적 코드 설계 (휴먼 에러 방지)

기획자나 레벨 디자이너가 월드에 에셋을 무작위로 배치하더라도 오작동이 일어나지 않도록, C++ 헤더 선언부에서 변수의 최소 기본값을 강제 고정하는 방어적 구조를 수립하였다.

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item Data")
int32 Quantity = 1;

🟧 4. 포스트 프로세스 머티리얼 (Custom Stencil 외곽선) 구현 및 최적화

🟦 이슈 1: 해상도 종속성에 따른 외곽선 두께 변조 현상

  • 문제: UV 좌표를 0.002와 같은 고정된 정적 실수치(실수 오프셋)로 밀어내어 텍셀 외곽선을 검출할 경우, 출력 해상도(1080p vs 4K)의 픽셀 밀도 차이에 따라 외곽선의 물리적 두께가 달라져 비주얼 왜곡이 발생하였다.
  • 해결: 머티리얼 에디터 내에서 SceneTexelSize 노드를 도입하여 현재 디스플레이 해상도 기준의 정확한 1픽셀 물리 크기를 동적으로 역산하였다. 여기에 사용자 정의 파라미터(LineThickness)를 승산 처리함으로써 모든 뷰포트 환경에서 일정한 픽셀 두께를 유지하는 해상도 독립적(Resolution-Independent) 외곽선 셰이더를 완성하였다.

🟦 이슈 2: 데이터 타입 다형성 위배에 따른 컴파일 에러

  • 문제: 머티리얼 수식 연산 중 아래와 같은 타입 불일치 에러와 함께 셰이더 컴파일이 거부되었다.

Arithmetic between types float4 and float3 are undefined

  • 원인: 화면 버퍼를 샘플링하는 SceneTexture 노드는 투명도(Alpha)를 포함한 float4(RGBA) 구조를 반환하는 반면, 외곽선 지정을 위해 추가한 컬러 파라미터 변수는 float3(RGB) 구조를 출력하여 벡터 차원 불일치로 인한 사칙연산 불가 오류였다.
  • 해결: ComponentMask 노드를 파이프라인 중간에 배치하여 원본 렌더 타깃 픽셀 데이터에서 알파(A) 채널을 소거하고 R, G, B 채널만 명시적으로 추출(float4 ➔ float3)하였다. 데이터 규격을 3차원 벡터로 통일시켜 에러를 해결하였다.

🟧 핵심 요약

  • 유저 피로도를 최소화하기 위해 상호작용 탐색 구조를 에임 방식에서 캐릭터 중심의 Sphere Overlap 기반 최단 거리 검출 방식으로 개편
  • FOverlapResult 구조체 사용을 위해 Engine/OverlapResult.h 헤더를 명시적으로 포함하여 IWYU 빌드 에러 완화
  • 변수 초기화 누락(Quantity = 1) 및 데이터 테이블 Key 매핑 관계를 교체하여 데이터 누락 현상을 원천 방어
  • 포스트 프로세스 단계에서 SceneTexelSize 및 ComponentMask 노드를 연동하여 해상도 독립적이고 연산 오류가 없는 커스텀 스텐실 외곽선 머티리얼 인스턴스(MI) 시스템 구축