[🐹Project: HSR] #1 NPC 대화 시스템 데이터 기반 설계

2025. 8. 27. 01:31·도토리도굴단/Project: HSR 개발일지

1. NPC 대화 시스템

 

NPC 대화 시스템을 설계해야한다. 조건은:

- 로컬라이징: 여러 언어를 쉽게 추가할 수 있어야 한다.

- 조건부 대화: 퀘스트 상태나 플레이어의 특정 행동, 다른 NPC와의 대화 여부 등 수많은 조건에 따라 대사가 달라져야 한다.

- 연출: 대사 중간에 캐릭터 애니메이션이나 사운드, 카메라 효과 등이 동반되는 컷씬도 쉽게 컨트롤할 수 있어야 한다.

- 유지보수: 기획자가 csv 파일에서 대사를 관리할 수 있어야 한다.

 

이전 Aero Diner에서 사용한 방법처럼, 대화 csv와 이벤트를 담당하는 csv를 나눴고, 이전에 없던 대화 조건을 추가하기 위해 조건 시트를 하나 더 추가했다. 한 시트에 다 담으려다보면 피곤해져서 일단 나눠보고 나중에 합치는 게 좋을 것 같다.

1. dialogueData.csv

순수하게 텍스트만 담는 곳. 대사 ID, 언어별 텐스트만 관리한다. 여기서 Text Animation 에셋의 Rich Text를 사용할 수 있다.

dialogueID ko-KR en-US
ELDER_GREET_FALLEN 이런, 어디서 <shake>크게 넘어졌나</shake> 보군! Oh my, it looks like you took a <shake>nasty fall</shake>!

 

2. eventSequence.csv

연출의 순서를 정의하는 대본. 대사 출력(DIALOGUE), 애니메이션 재생(ANIM), 대기(WAIT) 등 모든 연출 이벤트를 시간 순서대로 담는다.

sequenceID step eventType arg1
SEQ_GREET_FALLEN 1 ANIM surprised
SEQ_GREET_FALLEN 2 DIALOGUE ELDER_GREET_FALLEN

 

3. dialogueTrigger.csv

가장 고민했던 부분. 어떤 조건에서 어떤 대본을 실행할지 결정하는 규칙의 모음이다.

triggerID priority requiredFlags forbiddendFlags stringConditions sequenceID
           
           

 

2. [Flags] 어트리뷰트

수많은 true/false 플래그를 효율적으로 관리하기 위해서 비트마스크와 [Flags] 어트리뷰트를 사용했다.

일단 비트마스크 제안한 동료 개발자 천재. 비트마스크 연산을 어떻게 효율적으로 쓸 수 있지 찾아보다가 [Flags] 어트리뷰트를 발견했다. enum은 보통 여러 선택지 중 하나를 나타내는 값으로만 사용하는데, 이 [Flags]를 사용하면 여러 상태의 조합을 효율적으로 관리할 수 있다.

[Flags]
public enum GameFlags : long // long으로 63개까지 확장 가능!
{
    TALKED_TO_ELDER = 1L << 0, // 1
    COMPLETED_MQ01  = 1L << 1, // 2
    PLAYER_JUST_FELL= 1L << 2, // 4
    // ...
}

[Flag] 어트리뷰트를 붙이면 enum을 단일 값이 아닌 여러 상태 플래그의 집합으로 취급하도록 만든다. 따라서 인스펙터에서 다중 선택으로 사용할 수 있다.

사용 조건

1. [Flags] 어트리뷰트 선언

[Flags] // enum 위에 선언
public enum CharacterState
{
    // ...
}

 

2. 값은 반드시 2의 거듭제곱으로 정의

각 enum 멤버가 고유한 비트 자리를 차지해야 하기 때문에 2의 거듭제곱 단위로 정의해야 한다. 비트 시프트 연산자를 사용하면 2의 n제곱 값을 가지게 할 수 있다. NONE은 정의하지 않아도 자동으로 정의된다.

[Flags]
public enum CharacterState
{
    NONE       = 0,      // 0000 0000 (아무 상태도 아님)
    CAN_WALK   = 1 << 0, // 1  (0000 0001)
    CAN_RUN    = 1 << 1, // 2  (0000 0010)
    CAN_JUMP   = 1 << 2, // 4  (0000 0100)
    IS_POISONED= 1 << 3, // 8  (0000 1000)
    IS_STUNNED = 1 << 4, // 16 (0001 0000)
}

3. enum은 int임을 고려하기

enum은 32비트 크기의 int를 사용하므로 최대 31개의 플래그를 가질 수 있다. 만약 더 선언하고싶다면 long으로 기반 타입을 변경할 수 있다.

[Flags]
public enum MoreFlags : long // 기반 타입을 long으로 지정
{
    FLAG_0  = 1L << 0,
    // ...
    FLAG_62 = 1L << 62,
}

아니면 여러 enum으로 나눠서 사용하는 것도 방법이다.

'도토리도굴단 > Project: HSR 개발일지' 카테고리의 다른 글

[🐹Project: HSR] #3 Unity Localization + Google Sheets 연동 및 후처리  (0) 2025.09.11
[🐹Project: HSR] #2 플레이어 데이터 수집, 플래그 체크  (0) 2025.09.09
'도토리도굴단/Project: HSR 개발일지' 카테고리의 다른 글
  • [🐹Project: HSR] #3 Unity Localization + Google Sheets 연동 및 후처리
  • [🐹Project: HSR] #2 플레이어 데이터 수집, 플래그 체크
happy124219
happy124219
happylaboratory 님의 블로그 입니다.
  • happy124219
    윤아 실험실
    happy124219
  • 전체
    오늘
    어제
    • 분류 전체보기 (116)
      • 공부방 (103)
        • Unity UI (2)
        • C# 알고리즘 (3)
        • C# 에러발생 로그 (7)
        • 내일배움캠프 Unity 9기 TIL (91)
      • 도토리도굴단 (9)
        • Project: HSR 개발일지 (3)
        • Project: HoP 개발일지 (6)
      • 개인 프로젝트 (1)
        • Project: BloomFolk (1)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    내일배움캠프후기
    게임개발
    스파르타내일배움캠프
    유니티
    내일배움캠프
    도망공부일지
    유니티트랙후기
    도망개발일지
    Unity게임개발
    c#문법
    스파르타내일배움캠프TIL
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
happy124219
[🐹Project: HSR] #1 NPC 대화 시스템 데이터 기반 설계
상단으로

티스토리툴바