Unity에서 NPC 대화 시스템을 만들 때 처음에는 대사 목록과 선택지만 있으면 충분해 보입니다. 하지만 기능이 조금만 늘어나도 금방 복잡해집니다. 호감도, 퀘스트 상태, 플레이어 선택, 이전 대화 기억, 조건 분기, 반복 대사 방지 같은 요소가 한 파일이나 한 컴포넌트 안에 섞이기 시작하기 때문입니다.
대화 시스템이 꼬이는 이유는 대사가 많아서가 아니라, 대화 문장, 조건, 상태, 의도, 결과가 같은 책임 안에 섞이기 때문입니다.
1. 대화 문장과 대화 조건을 분리합니다
NPC가 어떤 말을 하는지와 그 말을 언제 할 수 있는지는 다른 문제입니다.
- 대화 문장: 화면에 표시되는 텍스트
- 대화 조건: 퀘스트 진행도, 호감도, 소지 아이템, 이전 선택
- 대화 결과: 아이템 지급, 퀘스트 갱신, 관계 변화
이 세 가지를 하나의 분기문에 모두 넣으면 처음에는 빠르게 만들 수 있지만, 나중에 대사를 고칠 때마다 조건과 결과까지 함께 건드리게 됩니다. 작은 수정이 다른 대화 흐름을 망가뜨리는 이유도 여기서 시작됩니다.
2. NPC의 상태와 대화의 의도를 따로 봅니다
NPC가 같은 문장을 말하더라도, 그 문장의 의도는 상황에 따라 달라질 수 있습니다. 예를 들어 “다시 왔군요”라는 말은 단순 인사일 수도 있고, 퀘스트 실패 후의 반응일 수도 있고, 이전 선택을 기억하는 표현일 수도 있습니다.
따라서 대화를 설계할 때는 문장보다 먼저 의도를 나누는 편이 좋습니다.
- 인사
- 퀘스트 안내
- 거절
- 보상 지급
- 이전 선택에 대한 반응
- 관계 변화 표현
의도를 나누면 같은 NPC라도 현재 상태에 맞는 대화 묶음을 선택하기 쉬워집니다. 또한 나중에 대사를 교체하더라도 시스템 구조를 크게 바꾸지 않아도 됩니다.
3. 기억은 대화 데이터가 아니라 플레이 기록에 가깝습니다
“플레이어가 이 선택지를 골랐는가”, “이 NPC와 이미 처음 만났는가”, “이 퀘스트를 거절한 적이 있는가” 같은 정보는 대화 문장 자체가 아니라 플레이 기록입니다.
이런 값을 대화 노드 안에 직접 저장하면 테스트 중에는 편해 보여도, 저장/불러오기나 여러 NPC 간 공유 상황에서 문제가 생깁니다. 기억은 별도의 상태 저장소나 관계 시스템으로 빼고, 대화는 그 상태를 읽어 적절한 문장을 선택하는 구조가 더 안정적입니다.
4. 조건 분기는 줄이는 것이 아니라 위치를 정해야 합니다
대화 시스템에서 조건 분기를 완전히 없앨 수는 없습니다. 중요한 것은 조건이 어디에 있는지입니다.
- 대화 노드마다 조건이 흩어져 있는가?
- NPC 상태를 평가하는 별도 계층이 있는가?
- 퀘스트 시스템이 대화 시스템에 직접 끼어드는가?
- 대화 결과가 여러 시스템을 직접 수정하는가?
조건을 줄이는 것보다 조건의 위치를 일정하게 만드는 것이 유지보수에 더 중요합니다. 그래야 대화가 이상하게 나올 때 어디를 확인해야 하는지 알 수 있습니다.
5. 작은 구조로 시작하는 편이 좋습니다
처음부터 거대한 대화 에디터나 복잡한 그래프 시스템을 만들 필요는 없습니다. 먼저 다음 정도만 분리해도 충분히 효과가 있습니다.
- 대화 문장 데이터
- 대화 조건 평가
- 플레이어 선택 기록
- 대화 결과 처리
- NPC별 현재 대화 의도 선택
이 구조가 잡히면 이후에 ScriptableObject, JSON, 커스텀 에디터, 그래프 뷰 같은 표현 방식은 프로젝트 규모에 맞게 선택할 수 있습니다.
정리
NPC 대화 시스템이 복잡해지는 핵심 원인은 대사 수가 아니라 책임의 혼합입니다. 문장, 조건, 기억, 결과, 의도를 분리하면 작은 프로젝트에서도 대화 흐름을 훨씬 안정적으로 관리할 수 있습니다.
처음 만들 때는 “어떤 대사를 보여줄까”보다 “이 대사는 어떤 상태와 의도에서 선택되는가”를 먼저 정리해 보세요.
Unity에서 NPC 대화 구조를 실제 프로젝트 흐름으로 정리한 강의도 준비되어 있습니다. 먼저 맛보기판으로 접근 방식이 맞는지 확인할 수 있습니다.