대사 | Wwise와 Unreal Engine에서의 나레이션

Wwise에 대한 팁과 도구

현대 게임의 필수 요소 중 하나인 보이스오버 대사는 플레이어가 캐릭터를 특정 목소리와 연관지을 수 있을 뿐만 아니라 전반적인 억양을 통해 캐릭터의 감정을 더 잘 이해할 수 있게 해줍니다.
이 대사는 플레이어의 말이나 행동에 따라 캐릭터가 무엇을 어떻게 말할지를 변경하는 복잡한 대사 시스템을 통해 더욱 향상됩니다. 

플레이어가 과거에 도움을 준 적이 있던 캐릭터에게는 더 상냥하게 대한다거나 자신의 도덕적인 지침에서 심하게 벗어난 행동을 할 경우에는 더 공격적으로 대할 수 있죠. 이 시스템은 동적 대화라고 불립니다.

이 글에서는 나레이션 중심 대화를 중심으로 Wwise와 Unreal Engine을 사용하여 저희가 대사를 구현한 방법을 보여드리려고 합니다. Wwise에는 게임에 동적 대사를 구현할 수 있는 기능이 있지만, 일단 지금은 Wwise 대체 시스템을 사용해서 대화 시스템을 구동해보겠습니다. 다음은 이 글을 통해 살펴볼 3가지 주요 영역입니다.

1. 플레이어의 결정에 상관 없이 바뀌지 않는 시퀀스 컨테이너를 사용한 기본 나레이션.

2. 여러 언어로 게임을 설계하는 사용자를 위한 Wwise의 현지화 시스템.

3. 플레이어의 영향을 받는 변수를 기반으로 변경되는 스위치 컨테이너를 사용한 동적 나레이션.

이 데모는 Wwise의 시퀀스 및 스위치 컨테이너뿐만 아니라 이벤트 전송, 딜레이, 스위치, 상태 변경 등 Wwise에 관련된 Unreal Engine 블루프린팅도 배울 수 있게 해줍니다.

지난번에는 Wwise와 Unity에서 이 시스템을 구현하는 법에 대해 설명했습니다. 그 글은 여기에서 읽어보실 수 있습니다. 

Wwise – 시퀀스 컨테이너를 사용한 나레이션과 현지화

첫 번째로 지휘관이 플레이어에게 지시를 내리는 보이스오버를 설계해봅시다. 이 지시는 5개의 보이스 오버로 나눠지며 하나씩 차례대로 재생되도록 프로그래밍해야 합니다.

1. “Hello? Hello? Can you hear me? (여보세요? 여보세요? 제 목소리가 들리십니까?)”

2. “Oh good. Listen, I need you to do something very, very important for me. (아, 다행이군요. 자, 당신에게 아주 아주 중요한 임무가 있습니다.)”

3. “In front of you are these little... obstacles that I need you to overcome. (앞에 보이는 이 작은... 장애물들을 지나가야 합니다.)”

4. “I just need you to jump over the hurdle, go under the archway, and to the green path. Not the red one. That would be bad. (허들을 뛰어 넘고 아치형 입구 밑으로 들어간 다음 초록색 길을 따라가주세요. 빨간색을 밟으면 안됩니다. 상황이 안 좋아질 겁니다.)”

5. “If you could do that for me, that would greatly help us over here in corporate. Over and out. (이를 따라주신다면 여기 있는 저희에게 큰 도움이 될겁니다. 그럼 이만, 오버.)”

어떤 상황이 벌어지든 간에 이 나레이션은 절대 변경되지 않고 게임의 시작 부분에서 완전히 똑같이 재생됩니다. 그렇기 때문에 Sequence Container를 사용해서 아무 변경 없이 각 오디오 트랙이 차례로 재생되도록 할 수 있죠. 뿐만 아니라 Wwise의 현지화 시스템을 사용해서 플레이어의 환경 설정에 따라 오디오를 영어나 스페인어로 재생시키는 법도 살펴봅시다.

먼저 Audio 탭으로 가세요. Actor-Mixer Hierarchy 아래 MissionBriefing이라는 새로운 Sequence Container를 만드세요 (Ctrl + Shift + Alt + Q). 그리고 이 Sequence Container 아래 오디오 파일을 업로드하세요. Sequence Container를 우클릭하고 'Import Audio Files...'(Shift + i)를 선택하거나 오디오 파일을 Sequence Container 안으로 드래그하면 됩니다.

Audio File Importer에서 'Import as:' 입력란을 'Sound SFX'에서 'Sound Voice'로 변경하세요. 그런 다음 'Import'를 누르세요.

Sound Voice는 Sound SFX와 거의 같지만 Wwise 프로젝트에서 사용하는 모든 언어에 맞게 여러 오디오 파일을 가져올 수 있다는 점에서 다릅니다. 언어 설정이 변경되면 모든 Sound Voice는 해당 언어의 오디오 파일로 변경되죠.

이제 모든 영어 사운드 파일을 가져왔으니 Wwise 프로젝트에 다른 언어를 추가할 수 있도록 해봅시다. 상위 바에 있는 Project로 가서 Languages를 선택하세요 (혹은 Shift + J를 누르세요). Language Manager에서는 언어를 추가/제거하거나 이름을 변경할 뿐만 아니라 해당 언어의 모든 Sound Voice의 Gain을 변경할 수 있습니다. 여기서는 Add 버튼을 누르고 곧 뜨는 창에 Spanish를 입력하세요. 'Okay'를 누르고 곧바로 뜨는 경고 메시지에서 변경을 확인하세요.

새로운 Sound Voice 중 하나를 선택하면 Contents Editor에 영어와 스페인어에 대해 각 섹션이 생긴 것이 보입니다. 이미 영어 오디오 파일은 가져왔으니 Contents Editor의 Spanish 입력란으로 스페인어 오디오 파일을 드래그해 가져와봅시다. 5개의 모든 나레이션 사운드에 이 작업을 실행하겠습니다.

이 Sound Voice 중 하나를 재생하면 기본 언어로 들립니다. 하지만 Wwise의 상단 좌측 모서리에서 기본 언어를 Spanish로 변경한 후 다시 사운드를 재생하면 Spanish 입력란에 있는 사운드를 들을 수 있습니다. 이렇게 한 스위치만으로 개발자가 언어를 쉽게 변경할 수 있죠.

이번엔 Sequence Container를 살펴보겠습니다. 컨테이너를 선택한 후에 Contents Editor와 바로 오른쪽에 있는 Playlist 섹션을 보세요. 기본적으로 Sequence Container는 안에 있는 모든 사운드 오브젝트를 재생하도록 설정되지 않습니다. Playlist 안에 있는 사운드 오브젝트만 재생하게 되죠. Sound Voice를 재생하고자 하는 순서대로 Contents Editor에서 Playlist로 드래그하세요.

사운드를 편집해야 할 것이 아니라면 여기서 모든 작업이 끝납니다. 이제 Events 탭으로 가서 Default Work Unit 안에 2개의 새로운 이벤트를 만들어보겠습니다. 

1. Play_MissionBriefing: Sequence Container를 재생할 'Play' 동작이 있는 이벤트.

2. Reset_MissionBriefing: Sequence Container의 재생 목록을 첫 번째 Sound Object로 재설정해줄 'Reset Playlist' 동작이 있는 이벤트.

참고: 이 데모는 동적 대사 시스템을 작업하지만 Events 탭의 Dynamic Dialogue 섹션을 사용하지는 않습니다.

두 번째 이벤트는 Narration을 재생할 때마다 항상 Sequence Container의 첫 번째 사운드가 재생되도록 보장해줍니다. 안전 장치라고 할 수 있죠.

이제 사운드뱅크를 만들고 이 2개의 이벤트를 추가하면 됩니다. 상단 바에 있는 'Layouts'에서 Soundbank 레이아웃을 선택하거나 F7을 누르세요. Soundbank Manager에서 New를 선택하고 새로운 Soundbank를 만드세요. 저는 이 사운드뱅크를 Main이라고 하겠습니다. 

Soundbank Manager에서 새로 만든 Soundbank를 선택하고 Play_MissionBriefing과 Reset_MissionBriefing 이벤트를 모두 Event Viewer에서 Soundbank Editor로 드래그하세요.

Soundbank Manager에서 새로운 사운드뱅크의 플랫폼(Windows, Mac 등)과 프로젝트에서 사용하는 언어의 체크 상자를 확인하세요. 마지막으로 'Generate Selected' 버튼을 누르세요.

Wwise – 동적 대사

플레이어가 지휘관에게 임무를 받고 나면 임무를 수행할 시간이 주어집니다. 플레이어가 임무를 어떻게 완수하느냐에 따라 지휘관은 다른 반응을 보이게 되죠. 시작하기 전에 먼저 지휘관이 플레이어에게 할 말을 결정하는 변수를 매핑해봅시다. 먼저 플레이어에게 주어지는 3가지 목표를 살펴볼까요?

1. Go over the hurdle (허들 넘기).

2. Go under the archway (아치형 입구 아래로 지나가기). 

3. Go onto the green path, not the red path (빨간색이 아닌 초록색 경로 따라가기).

이 특정 임무는 여러 방법으로 완수할 수 있습니다. 정확히 말하자면 5가지 방법으로 완수할 수 있죠.

1. 아무 것도 하지 않을 경우. (실패, 실패, 실패)

2. 허들만 넘을 경우. (통과, 실패, 실패)

3. 플레이어가 허들을 넘고 아치형 입구 아래를 통과할 경우. (통과, 통과, 실패)

4. 플레이어가 허들을 넘고, 아치형 입구 아래를 지나가고, 붉은 경로를 따라갈 경우 (통과, 통과, 빨간색)

5. 플레이어가 허들을 넘고, 아치형 입구 아래를 지나가고, 초록색 경로를 따라갈 경우 (통과, 통과, 초록색)

추적해야 할 변수는 허들, 아치형 입구, 경로로 총 3개입니다. 이제 스위치와 상태 작업을 할 준비가 되었죠.

여전히 Soundbank 레이아웃에 있을 경우 'Layouts -> Designer'를 선택하거나 F5를 눌러서 Designer 레이아웃으로 돌아가세요.

Project Explorer의 Game Syncs 탭으로 가서 Default Work Unit의 Switch 섹션 아래 Hurdle, Archway, Path라는 3개의 새로운 Switch Group을 만들어 봅시다. Hurdle과 Archway 스위치 그룹에 모두 Fail과 Pass라는 2개의 스위치를 만들어 봅시다. 그런 다음 Path 스위치 그룹에는 Fail, Red, Green이라는 3개의 스위치를 만들어 봅시다.

Audio 탭으로 돌아가세요. Actor-Mixer Hierarchy에서 Default Work Unit 아래 새로운 Switch Container를 만드세요 (Ctrl + Shift + Alt + W). 저는 이 스위치 컨테이너의 이름을 MissionResult라고 하겠습니다. 

새로 만든 Switch Container를 선택하고 Property Editor의 오른쪽에 있는 'Switch' 설정을 보세요. 이 컨테이너에서는 먼저 Hurdle 시험을 통과했는지의 여부를 확인하게 됩니다. 시험에 실패했을 경우 지휘관의 실망스러운 오디오가 들리게 됩니다. 통과했을 경우에는 Archway 시험으로 넘어가게 되죠.

그러기 위해서 먼저 Switch Group을 Hurdle 그룹으로 설정하고 Default Switch/State를 Fail로 설정하세요. 그러면 Assigned Objects 섹션이 Pass와 Fail이라는 두 스위치로 구성됩니다. 여기에 올바른 '오브젝트'를 채워넣어야 합니다.

먼저 'Hurdle Failed' 조건의 새로운 오디오 파일을 MissionResult 스위치 컨테이너로 가져오세요. 그런 다음 MissionResult 컨테이너 안에 새로운 Switch Container를 만드세요. 저는 이 컨테이너를 Archway라고 하겠습니다.

이제 두 컨테이너를 모두 Contents Editor에서 각자 해당하는 Assigned Object로 옮기기만 하면 됩니다. 'Hurdle Failed'는 'Fail'로, 'Archway' 컨테이너는 'Pass'로 옮기세요.

그럼 이제 Archway 스위치 컨테이너 안에서 이 과정을 반복해봅시다. Switch Group을 Archway 스위치 그룹으로 설정하고 Default Switch/State를 Fail로 설정하세요. 'Archway Failed' 오디오를 Archway 컨테이너로 가져오고 Path라는 또다른 스위치 컨테이너를 만드세요. 그런 다음 아까처럼 Assigned Objects로 옮기세요. 'Archway Failed'는 'Fail'로, 'Path' 컨테이너는 'Pass'로 옮기면 됩니다.

마지막으로 이 과정을 다시 한 번 반복해봅시다. 하지만 이번에는 스위치가 2개가 아닌 3개네요. Path 스위치 컨테이너 안에 Switch Group을 Path 스위치 그룹으로 설정하고 다시 한 번 Default Switch/State를 Fail로 설정하세요.

이제 마지막 3개의 오디오 파일인 Path Failed, Path Red, Path Green을 가져오기만 하면 됩니다. 3개의 파일을 각자 해당하는 Assigned Objects로 가져오세요.

방금 끝낸 작업을 간단하게 되돌아봅시다. Hurdle 시험을 실패하면 나머지 스위치 컨테이너가 보이지 않고 그냥 실패 메시지가 재생됩니다. 통과할 경우 Archway 시험으로 넘어가죠. Archway 시험에 실패할 경우에는 Path 스위치 컨테이너가 보이지 않고 Archway 실패 메시지가 재생됩니다. Archway 시험을 통과하고 최종 Path 스위치 컨테이너로 넘어갈 경우 초록색이나 빨간색 경로를 따랐는지 혹은 아무 경로도 따르지 않았는지를 확인하게 되죠. 이 세 가지 조건은 모두 특정 오디오 파일을 재생하게 됩니다.

이렇게 작업을 모두 끝냈으니 이벤트를 만드는 것은 아주 간단합니다. Event 탭으로 가는 대신 Audio 탭에서 이벤트를 만들어봅시다. MissionResult 스위치 컨테이너를 우클릭한 다음 New Event에서 Play를 선택하세요. 그러면 Play_MissionResult라는 새로운 Play 이벤트가 자동으로 생성됩니다.

F7을 눌러 Soundbank 레이아웃으로 돌아가서 Play_MissionResult 이벤트를 Event Viewer에서 Soundbank Editor로 드래그하세요. 아까처럼 Soundbank를 생성하고 Wwise 프로젝트를 저장했는지 확인하세요.

Unreal Engine – 시퀀스 나레이션 통합하기

이제 Sequence Container에서 만든 나레이션을 통합해봅시다. 보통은 나레이션 오디오 파일을 차례대로 하나씩 다섯 번 재생하는 간단한 작업이죠. 하지만 한 오디오 파일이 끝나서 다음 파일을 재생할 준비가 되었다는 것을 어떻게 알 수 있을까요? 각 오디오 파일 사이에 약간의 딜레이를 넣고 싶다면요? 이 두 기능은 모두 이벤트 콜백과 코루틴(coroutine)이라는 것을 통해 만들어낼 수 있습니다.

먼저 뱅크를 로드해봅시다. Content Browser 안을 우클릭하고 'Audiokinetic -> Audiokinetic Bank'를 선택하세요. 새로운 뱅크의 이름을 Wwise에서 만든 Soundbank와 동일한 이름으로 지정하세요 (제 뱅크는 Main이었습니다).

이제 Wwise Picker 창이 있는지 확인해 보세요. 없을 경우 상단 바로 가서 'Window -> Wwise Picker'를 선택하세요. Wwise Picker에서는 모든 Wwise 컴포넌트를 볼 수 있습니다. 그렇지 않을 경우 Wwise에서 Soundbank를 다시 생성하고 Wwise 프로젝트를 저장하세요. 혹은 Unreal Engine의 Wwise Picker 창에서 'Populate' 버튼을 클릭하세요.

Event 폴더로 가서 3개의 이벤트를 Content Browser로 드래그하세요. Content Browser에 폴더를 만들어서 이벤트를 저장하면 정리에 도움이 됩니다. 이벤트를 모두 선택하고 우클릭한 다음 'Group into Soundbank'를 선택하세요. 방금 만든 뱅크를 찾아서 클릭한 다음 Select를 누르세요.

마지막으로 뱅크를 우클릭하고 Generate Selected Soundbank를 누른 다음 Generate를 누르세요.

이제 스크립팅을 시작할 준비가 되었습니다. 뷰포트 위에 있는 Blueprints 탭 아래에서 'Open Level Blueprint'를 선택하세요. Event 그래프에 빨간색 제목이 있는 여러 상자가 보일 거예요. 'Event BeginPlay'만 사용할 것이 다른 것은 무시하셔도 좋습니니다.

'Exec Pin' 흰색 화살표를 클릭하고 Event BeginPlay의 오른쪽으로 드래그하세요. 'Audiokinetic -> Actor -> Post Event'를 선택하거나 Search 바에서 'Post Event'를 검색해도 됩니다.

노드가 배치되면 여기로 전송할 Ak Event와 Event를 전송할 Actor라는 2개의 값을 연결시켜야 합니다. 이벤트 연결은 쉽습니다. 'Select Asset' 드롭다운 목록으로 가서 아까 만든 'Reset_MissionBriefing' 이벤트를 선택하세요.

이제 Actor를 추가해봅시다. 이 데모에서는 플레이어가 Actor입니다. 플레이어를 가져오기 위해서는 파란색 'Actor' 핀에서 클릭해서 드래그하거나 'Get Player Character'를 검색하세요.

이제 같은 작업을 반복해봅시다. 하지만 이번에는 약간 다른 점이 있습니다. Post Event에서 Exec 핀을 드래그하고 'Post and Wait for End of Event'를 검색해서 선택하세요. 이 함수는 나머지 스크립트로 진행하기 전에 해당 이벤트가 종료될 때까지 기다린 다음 이벤트를 전송해주는 편리한 함수입니다.

AkEvent의 경우 'Play_MissionBriefing' 이벤트를 선택하세요. 그리고 아까와 같은 'Get Player Character' 노드를 사용해서 함수의 Actor에 연결하세요.

지금까지 작업한 결과 Sequence Container의 재생 목록을 재설정한 다음 해당 컨테이너의 첫 번째 나레이션 오디오를 재생하도록 되어 있습니다. 이제 이 이벤트를 4번 더 재생하도록 해야 합니다. 딱 4번만 더요. 뿐만 아니라 각 나레이션 사이에 약간의 딜레이가 있으면 좋겠죠. 이것부터 작업해볼까요.

'Post and Wait For End of Event's' Exec 핀에서 Delay 함수를 검색해서 선택하세요. 이 간단한 함수는 정해진 Duration만큼 나머지 스크립트를 딜레이합니다. 저는 이 값을 1로 하겠지만 여러분이 원하는대로 설정해도 됩니다.

이제 새로운 정수 변수를 만들어야 합니다. 이 변수는 이벤트를 몇 번이나 재생했는지 세어줍니다. 이벤트를 다섯 번 재생하고 나면 이벤트가 다시 재생되지 않도록 해줘야 합니다.

새로운 변수를 만들기 위해서는 My Blueprint 창에 있는 Variables 탭에서 + 기호를 클릭하세요. 저는 이 변수를 NarrationCount라고 부르겠습니다. 새로운 변수를 만들 때마다 다른 작업을 하기 전에 먼저 Blueprint에서 'Compile' 버튼을 즉시 누르는 습관을 들이는 것이 좋습니다. 새로운 변수를 컴파일하면 변수의 더 많은 값을 편집할 수 있게 됩니다.

그런 다음 오른쪽에 있는 Details 창에서 Variable Type을 변경해봅시다. Variable Type의 드롭다운 목록으로 가서 Integer를 선택하세요. 이 변수에 해야 하는 작업이 끝났습니다.

Variables 탭에서 새로운 변수를 Event Graph에서 Delay 노드 아래로 드래그하여 놓으세요. 이 변수를 'Get'할 것인지 아니면 'Set'할 것인지 선택할 수 있는 기회가 주어집니다.

1. 변수의 값을 GET하세요 (저희의 경우 0이 되겠죠).

2. 변수를 NEW 값으로 SET 하세요 (이 값을 1526434568로 설정하겠습니다).

이제 Get Narration Count를 실행해봅시다. 이제 이벤트가 한 번 더 재생될 때마다 이 값을 1씩 증가시켜야 합니다. 그렇게 하기 위해서는 Narration Count의 핀을 드래그하고 'Increment Integer'를 검색해서 선택하세요. ++가 있는 노드가 생깁니다. 이 기호는 'Current Value + 1'을 의미합니다.

거의 다 됐습니다. 이제 이 이벤트가 5번 재생되었는지를 확인해야 합니다. 먼저 ++ 핀을 드래그하고 'Integer < Integer'를 검색해서 선택하세요. < 함수의 비어 있는 핀에서 5라는 값을 입력하세요.

< 함수의 빨간색 핀에서 'Branch' 매크로를 검색해서 선택하세요. 이 브랜치는 구문의 true/false 여부를 확인해줍니다. 저희의 경우 Narration Count가 5보다 작거나 큰지를 확인해야 하죠. 5보다 작을 경우 다시 돌아가서 이벤트를 재생해야 합니다. 5보다 작지 않을 경우에는 나레이션이 끝나야 하죠.

그렇게 하기 위해서 Branch의 True Exec 핀을 'Post and Wait for End of Event' 함수의 가장 왼쪽 Exec 핀으로 드래그하세요.

참고: 이렇게 하면 모든 노드를 통과하는 흰색 선이 생기게 되는데, 이게 보기에 안 좋을 수 있습니다. 흰색 선을 더블 클릭해서 Reroute Node를 만들면 노드를 통과하는 대신 피해가도록 할 수 있어요.

이렇게 작업이 끝났습니다! 블루프린트가 다음과 같이 됩니다.

메인 에디터로 돌아가기 전에 반드시 블루프린트를 컴파일하고 작업을 저장하세요. Play를 눌러서 잘 작동하는지 확인해 보세요. 나레이션 오디오 사이의 딜레이가 너무 적거나 많다면 Delay 함수에서 Duration 값을 조절해 보세요.

Unreal Engine – 미션 결과 통합하기

이제 플레이어가 미션 브리핑을 들었으니 미션을 실행해야 합니다. 게임은 플레이어가 정말로 허들을 넘고, 아치형 입구 아래를 지나가고, 초록색이나 빨간색 경로를 따라갔는지를 알아내야 합니다. 그렇게 하기 위해서 허들, 아치형 입구, 경로에 해당하는 상자 트리거를 만들어봅시다.

'Place Actors' 창의 Basic 탭에서 아래로 스크롤하여 Box Trigger 액터를 선택하고 뷰포트 안으로 드래그하세요. 이 Box Trigger를 플레이어가 '반드시 접촉하게' 되는 곳에 배치해야 합니다. Translate (w), Rotate (e), Scale (r) 도구를 사용해서 상자를 마음껏 조정해 보세요.

Hurdle 상자 트리거의 경우 Details 창으로 가서 파란색 'Blueprint/Add Script' 버튼을 선택하세요. 곧 열리는 스크린에서 원하는대로 Blueprint의 이름을 지어주세요. 저는 BP_SetSwitch라는 이름을 지어주겠습니다. Select를 누르면 Blueprint가 열립니다.

열리고 나면 Event Graph 탭으로 가세요. 여기서는 Hurdle에 해당하는 Wwise Switch를 Pass로 설정해서 플레이어가 정말로 허들을 넘어갔음을 알려줘야 합니다. 올바른 오브젝트가 Box Trigger 안으로 들어갈 때 활성화되는 Event ActorBeginOverlap라는 Event만 사용하면 되죠. 여기에서 플레이어가 트리거와 접촉하고 있는지를 확인해야 합니다.

Exec 핀에서 'Cast to PlayerController'를 검색해 선택하세요. 그리고 또 다른 Actor 핀을 'Cast to PlayerController'의 Object 핀과 연결하도록 하겠습니다.

그리고 Cast의 Exec 핀에서 'Set Switch' 함수를 검색해 선택하세요. 'As Player Controller' 핀에서 'Actor' 핀으로 드래그하세요.

이제 드롭다운 메뉴에서 Switch Value를 선택하는 대신 Switch를 별도의 변수로 설정해봅시다. 이렇게 하는 이유는 Archway의 스위치를 설정하는 데에도 이 블루프린트를 사용하게 되기 때문에 스위치를 서로 다른 2개의 값으로 설정할 수 있어야 하기 때문이죠.

그렇게 하기 위해서 Switch Value 핀을 드래그해서 'Promote to Variable'을 선택하세요. 이렇게 하면 변수의 이름과 유형이 Ak Switch Variable로 자동 설정됩니다. 바로 저희가 원하는 설정이죠. 이제 변수의 바로 오른쪽에 있는 아이콘을 눌러서 스위치를 켜기만 하면 됩니다 (Details 창에 있는 'Instance Editable' 체크 상자를 선택해도 같은 작업이 실행됩니다).

Instance Editable(눈모양)은 해당 변수를 Public으로 설정합니다. 이 경우 두 가지 작업이 실행됩니다.

1. 다른 블루프린트가 이 변수를 받거나 편집할 수 있게 됩니다.

2. 현재 맵에 블루프린트의 인스턴스가 여러 개일 경우 각 인스턴스마다 이 변수에 (에디터에서) 다른 값을 설정할 수 있습니다.

메인 에디터로 돌아가기 전에 반드시 블루프린트를 컴파일하고 저장하세요. Viewport나 World Outliner에서 BP_SetSwitch를 선택하면 이제 Details 창에 Switch Value가 제공된 것이 보입니다. 여기에서 값을 Hurdle-Pass로 설정할 수 있습니다.

Archway에도 같은 작업을 실행해봅시다. BP_SetSwitch를 Content Browser에서 Viewport로 드래그하고 Hurdle과 마찬가지로 Archway 아래에서 조절하세요. 이제 Switch Value를 Archway-Pass로 설정하기만 하면 됩니다.

이제 빨간색과 초록색 경로에도 상자 트리거를 만들어봅시다. 이 트리거에는 조금 다른 작업을 실행해봅시다. 각 경로에 스위치를 설정하는 대신 플레이어가 이 경로 안으로 들어가자 마자 미션을 종료하도록 해봅시다. 그렇다면 새로운 블루프린트가 필요하겠죠.

상자 트리거를 드래그하고 경로의 윗부분을 완전히 덮어서 약간 위에 떠있도록 조정하세요 (저는 빨간색 경로에 작업을 해보겠습니다). 그런 다음 BP_SetSwitch와 같은 방식으로 새로운 블루프린트를 만들고 BP_Path라는 이름을 지정합시다.

Event Graph 안에 두 개의 변수를 만들어야 합니다.

- 이름을 NarrationEnd와 MissionComplete로 지정하세요

- 두 변수 모두 Boolean이어야 합니다.

- 둘 다 Public이어야 하기 때문에, 눈 아이콘을 누르거나 Details 패널에서 'Instance Editable' 체크 상자를 선택하세요.

이 변수가 하는 일은 이름에서 알 수 있습니다. 나레이션이 끝났나요? 나레이션이 이미 완료되었나요? 첫 번째 변수는 미션 브리핑이 종료되기 전에 미션이 끝나지 않도록 해줍니다. 그리고 다음 변수는 미션이 두 번 이상 완료되지 않도록 해주죠.

이제 블루프린트를 컴파일하고 저장해 주세요. 그리고 다시 레벨 블루프린트로 돌아가봅시다. 레벨 블루프린트는 Blueprints 탭으로 가서 'Open Level Blueprint'를 선택하면 메인 에디터에서 접근할 수 있습니다.

여기에서는 나레이션이 끝났다고 Unreal Engine에게 알려주는 작업을 해야 합니다. 하지만 Narration End 변수는 다른 블루프린트에 있기 때문에 이 변수에 접근할 수 있는 방법이 필요하죠.

그러기 위해서 Branch의 False Exec 핀을 드래그하고 'Get All Actors Of Class'를 검색해서 선택하세요. Actor Class 입력란에서 방금 만든 블루프린트의 이름인 BP_Path를 찾으세요. 그리고 Out Actors 핀을 드래그하고 'Get (a copy of)'을 검색해서 선택하세요. 다시 한 번 드래그해서 또 다른 'Get (a copy of)'을 만드세요. 첫 번째 GET 함수의 값은 0이어야 하고 두 번째 GET 함수의 값은 1이어야 합니다.

이 두 개의 'GET'은 게임에 있는 2개의 BP_Path 액터인 빨간색 경로와 초록색 경로를 가져오게 됩니다.

한 블루프린트에서 두 경로의 액터를 여러 번 가져오게 되기 때문에 함수로 만드는 것이 유용하겠죠. 'Get All Actors of Class'와 두 'GET'을 모두 선택하고 우클릭한 다음 Collapse to Function을 선택하세요. My Blueprint 창의 Functions 탭 목록에서 새로운 함수의 이름을 Get Paths로 변경하세요. Get Paths 함수를 더블 클릭해서 Event Graph 안으로 들어가세요.

함수를 사용하기 전에 먼저 몇 가지를 변경해야 합니다. 먼저 Return Node가 필요합니다. 이게 없으면 두 GET 함수의 결과를 접근할 수가 없게 되죠. Event Graph 안을 우클릭하고 Add Return Node를 검색해서 선택하세요. Get All Actors Class 노드와 Return 노드의 Exec 핀을 연결하세요. 마지막으로 2개의 Get 함수로부터 파란색 노드를 Return Node로 드래그하세요. 그러면 Return 노드에 2개의 새로운 변수가 생깁니다. Return Node를 선택하고 Outputs 탭에 있는 변수의 이름을 지정하면 핀의 이름을 변경할 수 있습니다.

이제 'Get Paths' 노드를 선택할 일만 남았습니다. Details 창에서 'Pure' 체크 상자를 선택하세요.

Pure Function은 무슨 일이 있어도 클래스의 상태나 멤버를 변경하지 못하도록 해줍니다. 이 Actor 변수를 변경하지는 않고 가져오기만 할 저희에게 알맞은 함수죠.

이제 'Get Paths' 블루프린트를 닫고 Level Blueprint의 Event Graph 그래프로 돌아가세요. Get Paths 함수로부터 2개의 파란색 Path 핀이 보이실 거예요. 첫 번째 핀을 드래그하고 'Set Narration End' 노드를 만드세요. 그런 다음 두 번째 경로에도 같은 작업을 실행해 주세요. 모든 Exec 핀을 연결하고 나면 다음과 같이 됩니다.

이렇게 작업이 끝났습니다. 블루프린트를 컴파일하고 저장한 다음 BP_Path 블루프린트로 돌아가세요. BP_SetSwitch와 마찬가지로 Event ActorBeginOverlap을 사용해봅시다. Exec 핀을 이벤트에서 'Cast to PlayerController' 함수로 드래그하세요. 그리고 파란색 'Other Actor' 핀을 Cast의 오브젝트 핀으로 드래그하세요.

이제 임무 브리핑이 끝났는지의 여부를 확인해야 합니다. NarrationEnd 변수를 Variables 탭에서 Event Graph로 드래그하고 'Get NarrationEnd'를 선택하세요. 그런 다음 Exec 핀을 'Cast to PlayerController' 함수에서 Branch 함수로 드래그하세요. NarrationEnd 변수를 Branch의 조건과 연결하세요.

작업할 내용은 거의 같지만 이번에는 미션이 이미 끝났는지의 여부를 확인해야 합니다.

이제 브랜치 구성이 끝났으니 MissionComplete 변수를 true로 설정하고 Switch 값을 플레이어가 걸어간 경로로 설정한 후 'Play_MissionResult' Event를 플레이어에게 Post해줘야 합니다.

Set Switch의 Switch Value에서 Public 변수를 만드는 법을 기억하시나요? 기억이 안 난다면 BP_SetSwitch에서 작업한 것을 다시 확인해 보세요.

메인 에디터로 돌아가기 전에 반드시 블루프린트를 컴파일하고 저장해 주세요. 이제 Path로 가서 Switch를 'Path-Red'로 설정합시다. 그런 다음 이 경로를 복제해서 (Ctrl + W) Green Path에 맞게 조절하세요. 마지막으로 이 Switch Value를 'Path-Green'으로 설정하세요.

끝났습니다! 작업을 시험하기 위해서 미션 브리핑을 들은 다음 미션을 실행해 보세요. 초록색과 빨간색 경로를 모두 따라가보고 두 상황에서 모두 알맞은 Mission Result 대사가 들리는지 확인해 보세요.

지금까지는 게임에서 잘 작동하고 있습니다. 하지만 한 가지 문제가 있습니다. 현재 게임은 플레이어가 초록색이나 빨간색 경로를 따라갈 경우에 해당하는 두 가지 엔딩만 존재합니다. 그럼 Wwise에서 설정한 3가지 엔딩은 어떻게 하죠?

이를 수정하기 위해서 초기 나레이션이 끝난 후에 5초의 타이머를 만들어봅시다. 이 타이머가 미션이 끝나기 전에 완료될 경우 미션 결과를 전송하고 Mission Complete 변수를 true로 설정해서 플레이어가 다시 두 경로 중 하나로 돌아가서 미션을 다시 완료하지 못하도록 해줘야 합니다.

먼저 Level Blueprint로 돌아가세요. Narration End 변수를 true로 설정한 다음 Delay 함수로 타이머를 시작해봅시다. 2번째 'Set Narration End'의 Exec 핀을 Delay 함수와 연결하세요.

그런 다음 두 경로 중 하나를 따라가서 미션이 이미 완료되었는지를 확인해야 합니다. Functions 목록에서 GetPaths 함수를 드래그하세요. 그런 다음 두 Path 핀과 'Get Mission Complete'에서부터 모두 드래그하세요.

두 Mission Complete 불린이 모두 true가 아닐 경우 Mission Result 이벤트를 전송할 수 있습니다. 그렇게 하려면 다음과 같이 'OR boolean' 노드나 Branch를 사용하세요.

 

False Exec 으로부터 'Play_MissionResult'를 Player에서 전송해봅시다. 이전과 마찬가지로 'Post Event' 함수의 Actor 핀을 'Get Player Character' 함수로 드래그하면 됩니다.

이벤트를 전송하고 난 후에는 Mission Complete 변수를 true로 설정하기만 하면 됩니다. 그러기 위해서는 Get Paths 함수를 한 번 더 사용해서 Mission Complete를 GET하는 것이 아니라 SET해야 합니다.

 

전체 블루프린트는 다음과 같습니다. 

  

이제 저장한 후 작업을 시험해 보세요. 5가지 시나리오를 모두 시험해보고 다 올바르게 작동하는지 확인하세요. 그렇지 않을 경우 놓친 것이 없는지 작업을 확인해 보세요.
모두 올바르게 작동하나요? 축하드립니다! 성공적으로 작동하는 동적 대사 시스템이 완성되었습니다.

Jake Gamelin (제이크 겜린)

작곡가 | 강사 | 사운드 디자이너

Jake Gamelin (제이크 겜린)

작곡가 | 강사 | 사운드 디자이너

저는 미국 남부 캘리포니아에 살고 있는 작곡가이자 강사이며, 기술 사운드 디자이너입니다. 샌디에이고 주립대학교(San Diego State University)에서 음악 공부를 마치고, 소규모 비디오 게임 프로젝트에서 작업하며 상호작용 사운드 디자인과 음악을 배우며 동시에 가르치고 있습니다. 사운드 아티스트로서 제 스스로의 역량을 높이고 게임 오디오 분야에서 일하고 싶어하는 젊은이들을 양성하는 데 힘을 쏟고 있습니다.

https://www.jakegamelin.com/

Jake's YouTube Channel

 @CharaComposer

댓글

댓글 달기

이메일 주소는 공개되지 않습니다.

다른 글

ReaWwise: REAPER와 Wwise 연결하기

소개 Audiokinetic이 제작한 새로운 REAPER 확장을 드디어 공개합니다! ReaWwise는 REAPER 프로젝트에서 Wwise로의 오디오 에셋 전송을 간소화해줍니다....

5.10.2022 - 작성자: 앤드류 코스타 (Andrew Costa)

Wwise 2023.1 새로운 기능

Wwise 2023.1이 출시되었으며 Audiokinetic 런처를 통해 다운받으실 수 있습니다. 이 버전이 제공하는 새로운 기능을 간략하게 소개해드리려고 합니다....

7.7.2023 - 작성자: Audiokinetic (오디오키네틱)

Wwise 2023.1의 WAAPI

Wwise 2023.1은 2017년 API 도입 이후 가장 방대한 Wwise Authoring API (WAAPI) 업데이트를 포함하고 있습니다. 아직 Wwise 2023.1...

1.8.2023 - 작성자: 베르나르 로드리그 (Bernard Rodrigue)

WAQL 2.0

Wwise Authoring Query Language (WAQL, 와클) 첫 번째 버전이 출시된 지 벌써 몇 년이 지났습니다. 첫 버전 이후 크게 변경된 점은 없습니다. 가장...

10.8.2023 - 작성자: 베르나르 로드리그 (Bernard Rodrigue)

올바른 코덱 선택에 대한 안내

게임 오디오에서는 항상 오디오 파일을 압축해야 했습니다. 우리가 꿈꾸는 그대로의 오디오 환경을 모두 압축되지 않은 오디오 샘플로 두기에는 여전히 디스크 공간이나 메모리가 부족하다는...

14.5.2024 - 작성자: 마튜 장 (Mathieu Jean)

Wwise 출시 주기 변경 | Sim-Patch 출시 및 언리얼 엔진 프리뷰 개발 지원

이 글에서는 지난 몇 달 동안 Audiokinetic의 개발 프로세스에 적용된 몇몇 변경 사항을 공유하려고 합니다. 이러한 변경 사항은 Wwise가 더 자주 제공되어 더 빨리 다음...

28.5.2024 - 작성자: 기욤 르노 (Guillaume Renaud)

다른 글

ReaWwise: REAPER와 Wwise 연결하기

소개 Audiokinetic이 제작한 새로운 REAPER 확장을 드디어 공개합니다! ReaWwise는 REAPER 프로젝트에서 Wwise로의 오디오 에셋 전송을 간소화해줍니다....

Wwise 2023.1 새로운 기능

Wwise 2023.1이 출시되었으며 Audiokinetic 런처를 통해 다운받으실 수 있습니다. 이 버전이 제공하는 새로운 기능을 간략하게 소개해드리려고 합니다....

Wwise 2023.1의 WAAPI

Wwise 2023.1은 2017년 API 도입 이후 가장 방대한 Wwise Authoring API (WAAPI) 업데이트를 포함하고 있습니다. 아직 Wwise 2023.1...