Wwise SDK 2019.1.11
|
게임에서 뱅크를 어떻게 관리할 지 결정하기에 앞서 다음 문서를 자세히 읽어보시기 바랍니다.
유연성을 최대한 확보하고 대부분 게임 유형의 요구 사항을 충족시키기 위해 Wwise에서는 게임 내 뱅크 관리 방법과 관련해 새로운 접근 방식을 제공하고 있습니다. 이 새로운 방식은 기존 방식을 그대로 사용하면서도 좀 더 효과적인 제어권과 유연성을 제시해 자신의 게임의 요구 사항을 좀 더 효율적으로 관리할 수 있도록 돕습니다.
Wwise의 새로운 접근 방식은 기존 방식에 비해 다음 세 가지 부분이 개선됐습니다.
이 새로운 접근 방식의 주요 장점은, 미디어 콘텐츠를 여러 메모리 뱅크에 나눠 넣을 수 있다는 점입니다. 예를 들어, 전체 게임 음악이 하나의 이벤트로 시작된다고 가정합시다. 기존 방식을 이용할 경우 뱅크에 이벤트를 추가하면, 게임 끝에서만 재생되는 음악까지 포함해 메모리 내 관련 사운드와 미리 가져온 미디어까지 전부 자동으로 추가하게 됩니다. 게임 전체의 모든 미디어를 메모리에 저장하는 이런 방식은 매우 비효율적입니다. 그러나 Wwise의 새로운 접근방법을 이용하면 음악 미디어를 여러 뱅크로 나눠 넣어 특정 사운드가 재생돼야 할 때에만 로드하게 돼, 메모리를 효율적으로 관리할 수 있습니다.
여러 뱅크에 미디어를 나눠 넣으면 로드해야 할 미디어의 우선순위를 정할 수도 있습니다. 예를 들어, 메모리가 제한적인 경우 가장 중요한 미디어를 먼저 로드해야 할 것입니다. 비교적 덜 중요한 미디어는 별도의 뱅크에 저장해 메모리 공간이 충분할 때에만 로드할 수 있습니다. 예전에는 중요한 미디어와 중요하지 않은 미디어 파일 모두 동일한 뱅크에 포함됐었습니다. 한 뱅크가 메모리에 비해 너무 클 경우, 중요한 사운드는 커녕 심지어 아무 사운드도 재생되지 않는 경우도 있었습니다.
다음에 나올 부분은, 게임에 뱅크를 생성하고 통합하는 다양한 방법에 대해 설명합니다. 하나의 게임에서도 한 가지 이상의 방법을 조합하여 사용할 수 있습니다. 모든 게임은 서로 다르기 때문에 게임의 요구 사항에 따라 알맞은 방법을 선택해야 할 것입니다.
뱅크를 생성할 때 선택하는 내용에 따라 게임 내 오디오 에셋을 관리하는 작업량이 크게 좌우되며, 게임의 성능에 직접적인 영향을 끼칩니다. 사운드 디자이너와 오디오 프로그래머가 함께 이 문서를 꼼꼼히 살펴보고 앞으로 발생할 가능성을 예측해보는 것이 중요합니다. 협업을 통해 게임에서 중요시 하는 내용에 따라 적절한 전략을 세울 수 있을 것입니다. 어떤 솔루션이든 사용할 수 있지만, 메모리 사용량, I/O 접근, 게임 통합(integration)의 용이성을 고려해서 가장 적합한 전략을 선택해야 합니다. 각 방법에는 장점과 단점이 있기 때문에 대부분의 경우 메모리 사용과 통합의 용이성 사이의 균형을 찾는 것이 관건입니다.
이 방법을 사용하면 모든 이벤트 콘텐츠와 사운드 구조 데이터, 미디어 파일이 하나의 뱅크에 함께 저장되며 전부 동시에 메모리에 로드됩니다.
이 방법은 다음과 같은 상황에 적용할 수 있습니다.
물론 대부분의 게임은 보통 낭비할 만한 메모리가 없지만 이 방법은 사용하기와 유지하기가 아주 쉽다는 장점이 있습니다. 이 방법을 사용하는 가장 주된 이유는 바로 Wwise 프로젝트 전체를 최소 시간 안에 게임에 통합해야 할 경우입니다.
사용 방법:
Wwise에서
![]() |
참고: Events, Structures, Media 열 아래 체크 상자는 기본적으로 모두 선택되어 있습니다. 뱅크에 모든 것을 넣을 것이기 때문에 이렇게 이미 모두 선택된 것이 용이합니다. |
![]() |
작은 정보: 뱅크에 프로젝트 요소를 개별적으로 추가하지 않고 전체 Work Unit을 통째로 추가하면 Work Unit 콘텐츠의 변경 내용을 반영시키기 위해 뱅크를 재편집할 필요가 없다는 장점이 있습니다. Wwise는 SoundBank 안의 요소와 프로젝트의 요소 간에 활성화된 링크를 유지하기 때문입니다. 프로젝트 내 Work Unit에 변경사항이 생기면 자동으로 SoundBank가 업데이트됩니다. 이러한 방법을 사용하면 간단히 Generate 버튼을 누르는 것만으로 새로운 SoundBank 세트를 생성할 수 있습니다. |
![]() |
참고: 새로운 프로젝트에서는 기본 Work Unit만 사용 가능합니다. Work Unit이 더 만들어진 경우 이 Work Unit 또한 필요에 따라 뱅크에 추가되어야 합니다. |
게임에서
이 게임에는 SoundBank가 한 개만 존재하기 때문에, 게임을 초기화할 때 그냥 이 뱅크를 불러오면 됩니다. 물론 사운드 엔진이 반드시 먼저 올바르게 초기화되어야 합니다.
이 방법에 대한 추가 정보
장점:
단점:
![]() |
작은 정보: 이 방법은 게임 오디오를 빠르고 쉽게 통합하는 좋은 방법이지만, 프로젝트 개발이 끝나갈 때 즈음 게임 메모리 사용을 줄일 수 있는 방법으로 전환하는 일이 없도록 주의해야 합니다. |
이 방법은 다음과 같은 상황에 적용할 수 있습니다.
이 방법은 모든 소리가 게임에서 플레이어의 현재 위치에 의해서만 구동되는 싱글 플레이어 게임에 적합합니다. 콘텐츠를 여러 개의 뱅크로 나누어 넣으면 첫 번째 방법보다 메모리를 더 효율적으로 관리할 수 있으며, 그래도 비교적 쉽게 오디오를 게임에 통합할 수 있다는 장점이 있습니다.
사용 방법:
가장 먼저 뱅크를 어떻게 분할할 지 결정해야 합니다. 예를 들어 다음과 같은 방식으로 뱅크를 분할할 수 있습니다.
Wwise에서
게임에서
게임에서 적절한 시기에 알맞은 뱅크를 불러옵니다. 예를 들어 게임 초반에 일반 뱅크를 불러오고 플레이어의 실제 위치에 따라서 다른 적절한 뱅크를 불러올 수 있습니다. 일부 게임에서는 레벨 사이 전환 효과를 위해 동시에 여러 개의 '레벨'을 불러올 메모리가 충분히 있어야 한다는 점을 주의하세요.
이 방법에 대한 추가 정보
장점:
단점:
이 방법은 다음과 같은 상황에 적용할 수 있습니다.
사용 방법:
게임은 아주 복잡해질 수 있으므로 소리의 발생은 게임 텍스처, 시간대, 게임 오브젝트의 움직임, (온라인 멀티 플레이어 게임의 경우) 다른 플레이어의 동작과 같은 다양한 요인에 좌우됩니다. 예를 들어 이벤트나 오브젝트 중심의 환경에서는 다른 게임 오브젝트의 근접성에 따라 사운드를 메모리로 불러올 수 있습니다. 모든 게임은, 오브젝트가 주어진 범위 안에 있거나 단순히 존재할 경우 불러와야 하는 뱅크 목록을 가질 수 있습니다.
또한 Switch와 State가 재생할 사운드를 결정할 수 있습니다. 이벤트가 뱅크에 추가된 이런 사운드를 재생할 경우, 재생 가능한 모든 미디어가 자동으로 뱅크에 함께 추가됩니다. 예를 들어 'Play_Footstep'이라는 이름의 이벤트가 있다고 가정합니다. 이 이벤트는 현재 지면의 텍스처에 따라 알맞은 소리를 재생하며, 이 소리는 Switch가 변경되면서 지정됩니다. 이 방법도 잘 작동하지만, 게임플레이가 런던의 한 건물 안에서 일어나고 있을 경우 'footstep_sand.wav'(모래 발자국 소리)나 'footstep_winter.wav'(겨울 발자국 소리) 사운드를 메모리에 유지하는 것은 낭비일 것입니다.
이러한 메모리 낭비를 피하려면 이벤트 혹은 사운드 구조를 뱅크에 불러온 다음 이 뱅크에 들어갈 사운드를 지정할 수 있습니다. 예를 들어 여러 가지 지표면에 따른 발자국 소리를 사용할 경우, 다음과 같은 뱅크를 생성할 수 있습니다.
Wwise에서
앞의 예제를 재생성하는 방법:
게임에 세 가지 다른 텍스처가 있다고 가정합시다 (눈, 모래, 콘크리트). Wwise에서 'ground_texture' Switch에 따라 세 개의 Random Container 중 하나를 재생하는 Switch Container가 있습니다. 세 가지 Random Container는 각각 주어진 텍스처에 따라 네 개의 다른 발자국 소리를 가지고 있습니다.
![]() |
참고: Random Container 전체를 드래그해서 놓는 대신 각 사운드를 개별적으로 드래그해도 됩니다. 하지만 컨테이너를 사용하면 컨테이너 안의 모든 사운드가 자동으로 뱅크에 추가되기 때문에, 컨테이너의 내용이 변경될 경우 변경 사항을 수동으로 적용하지 않아도 된다는 장점이 있습니다. |
이제 네 개의 뱅크가 생겼습니다. 한 뱅크는 재생할 오디오에 관한 이벤트와 구조 데이터를 담고 있으며 나머지 세 뱅크는 특정 지표면에 연결된 미디어만 담고 있습니다.
게임에서
이 방법에 대한 추가 정보
이 예시는 이 방법을 통해 실행할 수 있는 수많은 예시 중에서 아주 특정한 한 예시일 뿐입니다. 모든 뱅크에서 한 사운드씩, 한 이벤트씩 들어갈 내용을 개별적으로 결정할 수 있기 때문에 각 뱅크의 콘텐츠를 완전히 통제할 수 있습니다. 게임의 각 사운드마다 별도의 뱅크를 만들 수는 있지만, 이 경우 새로운 사운드가 생길 때마다 게임의 적절한 위치에 뱅크를 불러올 새로운 코드가 필요하기 때문에 유지 관리가 굉장히 어려워집니다. 각 게임은 세분성(granularity)과 게임 통합의 용이성 사이의 균형을 찾는 것을 목표로 합니다.
![]() |
작은 정보: 사운드 불러오기 방식에 대해 관심이 있다면 LoadBank 대신 PrepareEvent API나 PinEventInStreamCache API, SetMedia API 사용 방법을 살펴보는 것도 좋은 방법입니다. |
장점:
단점:
이 방법은 다음과 같은 상황에 적용할 수 있습니다.
준비된 이벤트란 정확히 무엇일까요? PrepareEvent 기능을 호출할 경우 시스템은 이벤트를 분석해서 이 이벤트에 연관된 모든 구조체와 미디어가 메모리에 로드됐는지 확인합니다. 모든 내용이 메모리에 올라가지 않았을 경우 시스템은 누락된 정보를 자동으로 디스크에서 스트리밍합니다. 이벤트는 명시적으로 준비 해제하기 전까지 항상 준비된 상태로 유지됩니다.
사용 방법:
이 방법을 사용하려면 메타데이터(구조체와 Event)를 포함하고 있는 SoundBank로부터 미디어를 명시적으로 제외시켜줘야합니다. 필요한 경우, 구조체는 별도 SoundBank의 일부가 될 수 있습니다. 그러나 구조체 로딩이 뱅크 단위로 세분화돼있기 때문에 대부분의 경우 한 SoundBank 안에 이벤트로 포함시키는 것이 적절합니다.
PrepareEvent 기능을 사용할 SoundBank를 제작할 경우, 필요한 Event와 구조체가 적어도 하나의 SoundBank에 있어야 하며 반드시 파일 시스템 내 루즈 파일(loose file)로 미디어에 접근할 수 있어야 합니다. 특정 뱅크가 참조하는 미디어가 다른 어떤 뱅크에도 포함돼있지 않은 경우, CopyStreamedFiles 도구는 이 미디어가 PrepareEvent API로 사용되며 루즈 파일을 출력 디렉터리로 복사한다고 간주합니다.
Event를 준비하기에 앞서 해당 Event는 반드시 하나의 SoundBank에서 메모리로 로드돼있어야 합니다 (LoadBank() 이용). 그 이유는 바로 이 Event가 Event를 준비할 때 필요한 의존성에 대한 정보를 담고 있기 때문입니다.
Wwise에서
![]() |
참고: 하나의 뱅크에 담긴 구조체 데이터는 런타임 때 분할될 수 없습니다. 그렇기 때문에 AK::SoundEngine::PrepareEvent를 사용할 경우 별도의 뱅크에서 구조체 데이터가 필요하게 되면 해당 뱅크의 모든 구조체가 동시에 로드됩니다. 이러한 이유로 프로젝트의 구조체 콘텐츠를 여러 개의 뱅크로 분할함으로써 메모리에 로드되는 불필요한 정보를 최소화하는 것이 좋습니다. |
게임에서
이 방법에 대한 추가 정보
AK::SoundEngine::PrepareEvent 호출은 반드시 I/O 함수 호출로 간주돼야 한다는 점에 주의하세요. 이전 예시에서는 차단(blocking) 기능을 사용했습니다. AK::SoundEngine::PrepareEvent 함수의 다른 오버로드를 사용해 차단하지 않는 호출로 만든 후, 별도의 콜백을 통해 완료 알림을 다시 회복시킬 수 있습니다.
장점:
단점:
이 방법은 다음과 같은 상황에 적용할 수 있습니다.
이 방법은 기본적으로 이전의 방법(방법 4: 이벤트 준비)과 동일하지만, 이벤트가 준비될 때 불러오는 미디어를 더 잘 통제할 수 있습니다. 이 방법을 사용하면 준비된 이벤트 및 현재 활성화된 게임 싱크와 관련된 미디어만 메모리에 로드됩니다.
'Play_Maincharacter_FootSteps'와 'Play_Monster_Footsteps' 이 두 이벤트가 있는 간단한 프로젝트가 있다고 가정합시다. 각 이벤트는 이동하는 캐릭터가 서있는 지표면에 따라 여러 가지 소리를 무작위로 재생하는 서로 다른 Switch Container를 재생합니다. Switch Group의 이름은 'GroundTexture'이며 'Snow', 'Concrete', 'Sand' 이 세 가지의 State를 갖고 있습니다.
Wwise에서 Switch Container의 계층 구조는 다음과 같은 형태를 이루고 있습니다.
Switch_Container_Footstep_Main_Character
그리고
Switch_Container_Footstep_Monster
이 예시에서는 메모리에 잠재적으로 불러올 수 있는 18개의 사운드 (3개의 사운드로 이루어진 6개의 그룹)가 있습니다.
방법 4: 이벤트 준비 를 사용해도 되지만, 그럴 경우 이벤트별로 메모리에 올라간 6개의 사운드보다 더 작은 세분성을 가질 수 없게 됩니다. 방법 3: 세부 미디어 관리 를 사용하면 보다 세밀한 세분성 단위를 가질 수는 있지만 이 간단한 프로젝트에 6개의 다른 뱅크를 만들어야 합니다 (실제 프로젝트에서 뱅크의 수는 매우 빠르게 중가합니다). 그러면 몬스터가 나타날 때 어떤 지표면을 적용할 수 있는지 확인한 다음 알맞은 뱅크를 불러와야 합니다.
반면 여기 나온 '방법 5'를 사용할 경우 어떤 이벤트와 게임 싱크가 가능한지 지정한 다음 알맞은 미디어만 불러오면 됩니다. PrepareEvent를 이용할 경우 모든 미디어는 파일 시스템에서 루즈 파일로 사용할 수 있어야 합니다.
사용 방법:
Wwise에서
게임에서
![]() |
참고: 하나의 뱅크에 담긴 구조체 데이터는 런타임 때 분할될 수 없습니다. 그렇기 때문에 AK::SoundEngine::PrepareEvent를 사용할 경우 별도의 뱅크에서 구조체 데이터가 필요하게 되면 해당 뱅크의 모든 구조체가 동시에 로드됩니다. 이러한 이유로 프로젝트의 구조체 콘텐츠를 여러 개의 뱅크로 분할함으로써 메모리에 로드되는 불필요한 정보를 최소화하는 것이 좋습니다. |
![]() |
참고: AK::SoundEngine::PrpareEvent와 AK::SoundEngine::PrepareGameSync 중 어느 것을 먼저 호출하는지는 중요하지 않습니다. State가 바뀔 때마다 이벤트와 게임 싱크를 서로 맞춰보고 이에 따라 미디어 풀이 업데이트됩니다. |
이 방법에 대한 추가 정보
장점:
단점:
프로젝트를 등록하세요. 아무런 조건이나 의무 사항 없이 빠른 시작을 도와드리겠습니다.
Wwise를 시작해 보세요