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 |