kwivaro웹 도구
UNREAL · 게임 시스템

대화에 몽타주·아이템 보상 붙이기

게임 클라이언트 개발자2026-09-106분

이미 있는 대화 시스템에 인사 몽타주, 대화 끝날 때 아이템 보상, 대화 중 순찰 정지/재개를 추가하고 싶었다. 단, 이미 잘 돌아가는 상점 NPC들은 손대고 싶지 않았다. 핵심은 ‘다시 만들지 말고 옵션으로 확장’이었다.

있는 걸 재사용하고, 없는 것만 옵션으로 추가

대화 트리(DT), 대화 컴포넌트, 상호작용 컴포넌트는 이미 있었다. 없던 세 가지만 얹었다.

  • 몽타주 재생: PlayAnimation() 단일 노드 모드 대신 AnimInstance->Montage_Play(GreetingMontage)를 DefaultSlot으로 재생. 그래야 대화 중에도 상태 머신이 유지된다.
  • 아이템 보상: 대화 종료 콜백(CloseConversation())에서 TryGrantItemReward() 호출, 확률 가중 풀에서 선택.
  • 순찰 정지/재개: 순찰 AIController의 Deactivate()/Reactivate()를 대화 시작·종료에 연결해, 말 거는 동안엔 멈추고 끝나면 다시 걷게 했다.

기존 애니메이션 필드 옆에 몽타주 필드를 옵션으로 추가했더니, 이 기능이 필요 없는 상점 NPC들은 변경이 하나도 없었다.

함정 — DataTable의 TArray<FText> JSON이 조용히 깨진다

대화 대사를 TArray<FText>로 다루는데, 이 필드를 JSON으로 직렬화해 쓰면 성공했다는 응답이 오는데도 실제 배열 내용이 조용히 손상됐다. 배열 필드를 지나는 JSON 경로 자체가 문제였다. 우회는 간단했다. CSV export/fill 사이클로 배열 필드 JSON 경로를 아예 피했다.

배운 점

이미 있는 걸 다시 만들지 말고, 없던 것만 옵션 필드로 얹으면 하위 호환이 저절로 지켜진다. 애니메이션 필드에 몽타주 필드를 ‘추가’한 덕에 기존 NPC 일곱은 그대로 살았다.

DataTable의 TArray<FText>는 JSON 쓰기에서 조용히 깨질 수 있다. 성공 응답을 믿지 말고 읽어서 확인하고, 배열 필드는 CSV 경로로 다루는 게 안전하다.