TIL#63-Unreal C++ 팀 프로젝트 (6) : 스킬 UI 연동 점검과 HUD 디자인 개선

ㅎ12·2026년 9월 18일
post-thumbnail

📚 금일 학습 내용

  • 스킬 UI의 5단계 누적 점등 기능 확인
  • 실제 게임플레이와 스킬 UI 연동 점검
  • 스킬 연동 오류의 발생 구간 파악 및 담당자와 공유
  • 결과 화면의 승리·패배 처리 방향 확인
  • HUD 전체 디자인 검토 및 후속 작업 계획 수립

1. 스킬 UI 초기 상태 및 누적 점등 확인

: 기존에 제작한 WBP_SkillUI는 궁극기 스택을 5단계로 표현하는 원형 UI다.

기본 링은 유지하고, 스택이 증가할 때마다 마크가 하나씩 추가로 점등되는 방식으로 구성했다.

초기 표시 문제 ✔️

처음 게임을 실행했을 때 스택이 없는 상태에서도 마크가 전부 점등되어 있었다.

스택 변경 이벤트를 받았을 때만 Update Skill을 실행하는 구조에서는 게임 시작 직후의 표시 상태가 원하는 형태로 초기화되지 않을 수 있었다.

이에 Event Construct에서 Update Skill을 호출하고 Charge에 0을 전달하도록 수정했다.

Event Construct
    ↓
Update Skill
Charge = 0

수정 결과: 게임 시작 시 링만 표시되고 점등 마크는 보이지 않는 초기 상태를 확인했다.

누적 점등 테스트

Update Skill 함수에 숫자를 직접 입력해 표시 결과를 확인했다.

Charge표시 결과
0링만 표시
1첫 번째 마크 점등
2첫 번째 유지 + 두 번째 점등
31~3번 점등
41~4번 점등
5전체 점등

기존에 구현한 Charge >= 단계별 숫자 비교를 통해 누적 점등이 정상적으로 작동했다.

단, 이 테스트는 값을 직접 입력한 UI 표시 테스트이며, 실제 과녁 명중을 통한 스택 증가 테스트는 아니다.


2. 스킬 컴포넌트 델리게이트 연동

: 스킬 담당자로부터 공유받은 UI 연동 정보는 다음과 같다.

소유 클래스이벤트전달 값
UPlayerSkillComponentOnUltimateTargetStackChangedCurrentTargetStacks, RequiredTargetStacks

스택이 증가하거나 궁극기 사용으로 초기화될 때 변경된 값을 UI에 전달하는 델리게이트다.

위젯 EventGraph 구성

WBP_SkillUI에서 다음과 같이 바인딩했다.

Event Construct
    ↓
Get Owning Player Pawn
    ↓
Cast To BP_FPSCharacter
    ↓
Get Component by Class
(Player Skill Component)
    ↓
Bind Event to On Ultimate Target Stack Changed

델리게이트에 연결한 커스텀 이벤트는 OnStackChanged다.

OnStackChanged
    │
    ├─ Current Target Stacks
    │          ↓
    │    Update Skill.Charge
    │
    └─ 실행 핀 → Update Skill

Required Target Stacks는 현재 5칸으로 구성한 UI에서 별도로 사용하지 않았다.

확인한 결과

  • BP_FPSCharacter 캐스트 성공
  • Update Skill 수동 점등 정상
  • 실제 플레이에서는 OnStackChanged 이벤트가 호출되는 것을 확인하지 못함

따라서 UI 표시 로직은 확인했지만 실제 게임플레이 연동은 완료되지 않은 상태로 구분했다.


3. C++ 코드 분석으로 스택 증가 흐름 이해

: 실제 이벤트가 들어오지 않는 이유를 확인하기 위해 PlayerSkillComponent.cpp를 살펴봤다.

AddUltimateTargetStack()

void UPlayerSkillComponent::AddUltimateTargetStack()
{
    if (bIsUltimateActive)
    {
        return;
    }

    if (CurrentTargetStacks >= RequiredTargetStacks)
    {
        return;
    }

    ++CurrentTargetStacks;

    CurrentTargetStacks = FMath::Clamp(
        CurrentTargetStacks,
        0,
        RequiredTargetStacks
    );

    BroadcastTargetStackChanged();
}

: 궁극기가 활성화되지 않았고 최대 스택에 도달하지 않은 경우 현재 스택을 1 증가시킨다.

이후 BroadcastTargetStackChanged()를 호출해 변경된 값을 UI에 전달하도록 작성되어 있다.

BroadcastTargetStackChanged()

void UPlayerSkillComponent::BroadcastTargetStackChanged()
{
    OnUltimateTargetStackChanged.Broadcast(
        CurrentTargetStacks,
        RequiredTargetStacks
    );
}

: 델리게이트를 통해 현재 스택과 필요 스택을 전달한다.

ActivateUltimate()

: 궁극기 사용 조건을 만족하면 스킬을 활성화하고 누적 스택을 0으로 초기화한다.

CurrentTargetStacks = 0;

BroadcastTargetStackChanged();

따라서 정상적으로 연결된 경우 궁극기 사용 직후 UI의 점등 마크도 모두 꺼져야 한다.

정리한 데이터 흐름

과녁 명중
    ↓
AddUltimateTargetStack()
    ↓
CurrentTargetStacks 증가
    ↓
BroadcastTargetStackChanged()
    ↓
OnUltimateTargetStackChanged
    ↓
WBP_SkillUI.OnStackChanged
    ↓
Update Skill
    ↓
스택 수에 맞춰 점등

여기서 중요한 점은 UI가 스택을 직접 증가시키는 것이 아니라, 게임플레이에서 변경한 스택 값을 전달받아 표시한다는 것이다.


5. 보스 과녁 처리 코드 확인 및 오류 공유

: 과녁 명중과 스택 증가가 실제로 연결되어 있는지 확인하기 위해 보스 관련 코드를 살펴봤다.

ABossBerserkActor::TakeDamage()

유효한 피해를 받으면 보스에게 구체 파괴 사실을 전달한 뒤 구체를 제거한다.

if (ABossCharacterBase* Boss =
    Cast<ABossCharacterBase>(GetOwner()))
{
    Boss->HandleBerserkOrbDestroyed(this);
}

Destroy();

HandleBerserkOrbDestroyed()

해당 함수에서는 다음 처리를 확인했다.

  • 발악 패턴 진행 상태 확인
  • 파괴된 구체를 목록에서 제거
  • 남은 구체 수 감소
  • 구체가 모두 파괴되면 발악 패턴 종료

확인한 함수 내부에는 AddUltimateTargetStack() 호출이 없었다.

다만 플레이어의 사격 판정 코드 등 다른 위치에서 호출할 가능성이 있으므로, 이 코드만으로 프로젝트 전체에 스택 증가 연결이 없다고 단정할 수는 없었다.

담당자와 오류 공유 📳

처음에는 실제 플레이에서 UI 변경 이벤트가 들어오지 않는 현상을 전달했다.

이후 문제를 더 정확히 구분하면서 과녁 명중 시 스택 증가 함수가 실제로 호출되는지 확인이 필요하다는 점을 정리했다.

담당자가 직접 확인한 결과, 스택 자체가 증가하지 않는 것으로 보인다는 답변을 받았으며 오류 수정이 진행되었다.

현재 상태: 수정 PR 제출 소식은 확인했지만, 수정본을 적용한 실제 UI 연동 테스트는 아직 진행 전이다.


UI가 갱신되지 않을 때 무조건 위젯부터 수정하는 것이 아니라, 데이터가 만들어지는 지점부터 확인해야 한다. ✔️

이번 사례에서는 다음 두 문제를 구분하는 것이 중요했다.

  1. 게임플레이에서 스택 자체가 증가하지 않는 문제
  2. 스택은 증가하지만 UI가 변경 이벤트를 받지 못하는 문제

실제 스택 증가 여부를 확인하기 전에는 어느 쪽이 원인인지 확정할 수 없었다.


5. 결과 화면 및 GameMode 작업 확인

: 기존에 제작한 결과 화면 위젯은 WBP_ResultScreen이다.

버튼 동작은 다음과 같이 구성했다.

버튼동작
MAIN MENUL_MainMenu 레벨 열기
RE:STARTGameMode의 RestartBattle() 호출

GameMode 담당자로부터 재시작 버튼 연결을 완료했다는 내용을 공유받았다.

또한 현재 승리 UI만 있는 상태이므로 패배 UI가 완성되면 알려 달라는 요청을 받았다.

결과 화면 구성 방향 ✅

별도의 결과 위젯을 추가하기보다는 기존 WBP_ResultScreen에서 승리와 패배를 구분해 표시하는 방향을 검토했다.

전투 종료
    ↓
WBP_ResultScreen
    ├─ 승리 → VICTORY
    └─ 패배 → DEFEAT

재시작과 메인 메뉴 버튼은 공통으로 사용할 수 있다.

주의: 결과값에 따른 실제 문구 및 연출 전환은 아직 구현 완료로 확인되지 않았다.


6. HUD 디자인 재검토

: 기존 HUD의 주요 기능과 배치는 구성했지만, 실제 플레이 화면을 확인했을 때 전체적인 디자인이 통일되지 않는다는 문제가 있었다.

현재 구성은 다음과 같다.

  • 상단 중앙: 보스 이름 및 HP바
  • 화면 중앙: 크로스헤어
  • 좌측 하단: 플레이어 HP·스태미나
  • 우측 하단: 무기·탄약·아이템
  • 우측 하단 끝: 원형 궁극기 UI

발견한 디자인 문제

① 플레이어 HP·스태미나

얇은 직선 바 형태로 정리되어 있으나, 장식이 강한 궁극기 UI와 디자인 차이가 크다.

② 무기·아이템 영역

총기, 탄약, 포션, 예비 탄약이 반투명 사각 패널 안에 모여 있지만 이미지·텍스트 정렬과 슬롯 구분이 불명확하다.

③ 궁극기 UI

보라색 원형 장식과 발광 효과가 강해 다른 HUD 요소보다 시각적 존재감이 크다.

④ 보스 HP바

상단 중앙에 길게 배치되어 있어 전체 길이와 좌우 여백을 재검토할 필요가 있다.

개선 방향 ✅

HUD 전체를 처음부터 다시 제작하기보다는 기존 기능을 유지하면서 시각적 규칙을 통일하기로 했다.

우선 우측 하단부터 수정할 예정이다.

  • 무기 이미지와 탄약 텍스트 정렬
  • 포션·예비 탄약 슬롯의 크기 및 간격 통일
  • 반투명 배경 색상과 형태 조정
  • 궁극기 UI의 크기와 발광 강도 검토

이후 플레이어 HP·스태미나 및 보스 HP바와의 디자인 균형을 다시 확인한다.


현재 상태

  • 기존 UI 작업 커밋 완료
  • 브랜치 변경 없이 작업 진행
  • 다른 담당자의 브랜치를 직접 머지하지 않음
  • 스킬 수정본 반영 후 실제 연동 테스트 예정
  • 결과 화면 승리·패배 전환 진행 예정

우선 작업 계획

  • HUD 디자인 수정
  • 무기·탄약·아이템 영역 정렬
  • 스킬 UI 외형 개선
  • 히트마커 디자인 및 애니메이션 준비
  • 데미지 텍스트 디자인 및 애니메이션 준비
  • 사운드 이펙트 리소스 준비

실제 게임플레이 이벤트와 연결해야 하는 작업은 관련 기능의 반영 상태를 확인한 뒤 진행한다.


Remind Point

• 델리게이트는 값을 생성하는 기능이 아니다

OnUltimateTargetStackChanged는 스택을 증가시키는 함수가 아니라 이미 변경된 스택 값을 다른 객체에 알려주는 이벤트다.

스택을 증가시키는 역할은 AddUltimateTargetStack()이 담당한다.

• 함수 구현과 실제 호출은 다르다

C++에 AddUltimateTargetStack()이 구현되어 있어도, 과녁 명중 시 해당 함수를 호출하는 연결이 없다면 스택은 증가하지 않는다.

함수가 존재한다는 사실과 실제 게임에서 실행된다는 사실을 구분해야 한다.

• 수동 테스트와 통합 테스트는 다르다

Update Skill(1)을 직접 호출해 마크가 켜지는 것은 UI 표시 로직 테스트다.

실제 과녁을 맞혔을 때 스택이 증가하고 UI가 갱신되는지는 별도의 통합 테스트가 필요하다.

• 디버깅은 데이터 흐름을 따라 진행한다

입력·명중 판정
    ↓
게임플레이 값 변경
    ↓
델리게이트 호출
    ↓
UI 이벤트 수신
    ↓
화면 갱신

문제가 발생하면 확인된 단계와 확인되지 않은 단계를 구분하고, 실제로 값이 생성되는 지점부터 추적해야 한다.

• 협업에서는 담당 범위를 구분한다

UI 담당자가 화면 표시 로직을 확인했더라도 게임플레이 데이터가 전달되지 않으면 전체 기능은 완성되지 않는다.

다른 담당자의 코드를 임의로 수정하기보다, 확인한 현상과 필요한 연결 지점을 구체적으로 공유하는 것이 중요하다. 아무래도


[학습 후 느낀 점과 개선하고 싶은 점]

: 이번 작업에서는 스킬 UI의 초기 상태와 5단계 누적 점등을 구현하고 수동 테스트까지 완료했다. 그러나 실제 플레이에서 UI가 갱신되지 않아 스킬 컴포넌트와 보스 과녁 처리 코드를 확인하게 되었다.

처음에는 UI 바인딩 문제에 집중했지만, 이후 스택 자체가 증가하는지 먼저 확인해야 한다는 점을 알게 되었다. 특히 함수 구현, 실제 함수 호출, 델리게이트 전달, UI 갱신은 각각 다른 단계라는 것을 코드 분석을 통해 이해했다.

담당자와 확인한 결과 스택 증가 오류가 발견되어 수정이 진행되었으며, 수정본 반영 후 실제 연동을 다시 검증할 예정이다.

HUD 디자인도 현재 기능을 유지하면서 전체적인 통일감을 개선하는 방향으로 정리했다. 다음 작업에서는 우측 하단의 무기·아이템·궁극기 영역부터 수정하고, 이후 결과 화면 전환과 실제 스킬 연동 테스트를 마무리할 계획이다.

0개의 댓글