버전

menu_open
알림: 고객님의 주요 출시 버전( 2019.1.11.7296 )에 해당하는 최신 설명서로 이동했습니다. 특정 버전의 설명서를 보시려면 Audiokinetic 런처에서 오프라인 설명서를 다운로드하고 Wwise Authoring의 Offline Documentation을 확인하세요.
Wwise SDK 2019.1.11
Wwise 모션 통합하기

모션(motion)은 사용자가 컨트롤 인터페이스의 햅틱 피드백 제어를 사용할 수 있도록 허용하는 기능입니다. Wwise로 오디오를 관리할 때 사용하는 것과 동일한 기능으로 애플리케이션의 모션을 관리할 수 있습니다. 내부적으로 모션 데이터는 오디오 데이터와 차이점이 없습니다. 즉, 오디오에서 이용 가능한 모든 기능을 모션에서도 사용할 수 있다는 뜻입니다. Wwise 모션 기능으로 사용할 수 있는 햅틱 피드백에는 두 가지 타입이 있습니다. 프로젝트 내 오디오 신호를 사용해서 모션으로 변환하거나 Motion Generator 소스를 사용해 전용 모션 신호를 생성할 수 있습니다. 이 기능은 Windows에서 제공되는 컨트롤러로 Wwise 저작 도구에서 직접 테스트해볼 수 있습니다.

모션 컴포넌트

모션은 애플리케이션에서 동작하도록 Wwise 사운드 엔진 플러그인 시스템을 사용하며, 두 개의 모듈로 나뉠 수 있습니다. Motion Generator라는 오디오 음원과 Wwise Motion인 오디오 장치입니다. Motion Generator는 선택 사항이지만, 정밀하고도 유연하게 모션 디자인을 생성할 수 있는 강력한 도구입니다.

모션 싱크 플러그인

모션 싱크 플러그인은 사운드 엔진과 모션-레디 장치 사이의 연결 고리처럼 생각할 수 있습니다. 다른 싱크 플러그인과 같이 리스너로부터 데이터를 받으며, 이 데이터를 장치로 '나타내는' 역할을 담당합니다. 이 플러그인은 독립된 라이브러리 내에 있으며, 저작 도구와 애플리케이션 둘 다에 포함돼있어야 합니다. 더 많은 정보는 모션 구축 섹션을 참고하세요.

Motion Generator 소스 플러그인

Motion Generator(모션 생성기) 소스 플러그인은 햅틱 피드백 효과 처리를 설계하는 데 매우 유용하고도 정밀한 방법을 제공합니다. 다른 오디오 음원과 마찬가지로 곡선 기반의 햅틱 피드백을 생성하도록 Wwise 프로젝트에서 Sound SFX 노드에 모션 생성기를 추가할 수 있습니다. Sound SFX 노드의 Output Bus는 반드시 모션-레디 버스로 설정돼야 합니다.

모션 구축

애플리케이션에서 모션을 사용하기 위해서는 각 컴포넌트를 적절히 구축해야 합니다. 오디오 작업 과정에 적용되는 모든 개념은 모션에도 적용 가능하다는 점을 기억하세요. 모션은 동일한 버스와 리스너, 방사체를 사용합니다 ( 리스너 통합하기 참고).

Wwise Authoring 구축

사운드나 모션 데이터를 장치로 보내려면 라이선스가 있는 Wwise Motion ShareSet를 Wwise 프로젝트의 Audio Device 폴더에 추가해야 합니다. Audio Device 폴더는 Project Explorer의 ShareSets 탭에 있습니다. Wwise Motion ShareSet는 모션-레디 장치와 소통할 때 사운드 엔진이 사용하는 Audio Device 플러그인입니다. 이 플러그인은 Wwise Motion ShareSet를 상위 레벨 Audio Bus에 할당하는 데에도 결정적인 역할을 합니다. 모션 버스 라는 용어는 편의상 할당된 Wwise Motion ShareSet으로의 상위 레벨 Audio Bus를 의미합니다. 손쉽게 문제를 해결하고 모니터링하기 위해서는 프로젝트에서 단일 모션 버스 계층을 사용하는 것이 좋습니다. 이제 Sound SFX의 Output Bus를 모션 버스로 설정해 햅틱 피드백을 생성할 수 있습니다. 일반적으로 모션 버스를 사용하는 Sound SFX 구성요소는 Motion Generator 소스도 사용합니다. 오디오와 모션을 동시에 가지려면, Sound SFX에 Output Bus나 Auxiliary Bus로서 최소한 한 개의 모션 버스와 Audio Bus가 있어야 합니다.

게임 구축

게임에서 가장 먼저 해야 할 것은 AkMotionSink 가 호출되는 독립된 라이브러리로 연결하는 것입니다. 이 라이브러리는 지원하는 플랫폼의 표준 컨트롤러를 제공합니다. 또한 SDK\include \AK\plugin 에 위치한 AkMotionSinkFactory.h 파일도 포함시켜야 합니다. 이 파일을 포함하면 자동으로 플러그인을 등록하기 때문에 매우 중요합니다.

참고: Unity에서는 플러그인 라이브러리가 자동으로 관리됩니다. 즉 AkMotionSink 를 직접 추가할 필요가 없습니다.

지원하는 컨트롤러와 추가 요구사항에 관한 목록은 다음 표를 참고하세요.

플랫폼 장치 추가 요구 사항
Android 진동을 지원하는 Android 장치
iOS 지원하지 않음. iOS 장치의 다양한 햅틱 피드백 API는 Apple의 사양 제한으로 인해 Audiokinetic의 Motion 기능 지원 요구사항에 부합하지 않습니다.
Linux 지원하지 않음.
Mac 지원하지 않음.
PlayStation 4 DUALSHOCK 4
PlayStation Move
Switch Joy-Con
Windows Xbox One 컨트롤러
Xbox 360 컨트롤러
DirectInput 컨트롤러
XInput.lib
Dinput8.lib
Winmm.lib
UWP UWP Gamepad C++/CX
XboxOne XboxOne Controllers Use the Id stored in a IGamepad object. XboxOne XDK XboxOne Controllers Use the Id stored in a IGamepad object.
XboxOne GDK Use AK::SoundEngine::GetGameInputDeviceID() from AK/SoundEngine/Platforms/GX/AkGXSoundEngine.h

A dedicated output needs be added for each device your application wishes to use motion with. 예를 들어, 4인 플레이어가 연결된 분할 화면 게임은 햅틱 피드백을 받을 수 있는 컨트롤러를 위해 네 개의 서로 다른 출력을 추가해야 합니다. 출력 장치를 추가하려면 Wwise API 함수 AK::SoundEngine::AddOutput 을 사용해서 AkOutputSettings 매개 변수에 ShareSet 이름을 지정해 줍니다. (Wwise 프로젝트에 정의된 것과 동일한 이름) 추가로, 복수의 장치가 연결되어 있기 때문에 장치 ID를 제공해줘야 합니다. 장치 ID에 관한 더 많은 정보는 다음 표를 참고하세요. 단일 컨트롤러를 사용하는 경우, 간단한 구축을 위해 기본 장치 ID가 지원됩니다. '0'으로 사용하면 첫 번째로 연결된 모션 지원 장치가 Motion 싱크의 대상이 됩니다.

플랫폼 장치 정보
Android 진동을 지원하는 Android 장치 0을 사용
iOS 지원하지 않음 -
Linux 지원하지 않음 -
Mac 지원하지 않음 -
Windows XboxOne 컨트롤러
Xbox360 컨트롤러
0에서 3 사이의 플레이어 인덱스를 사용합니다.
Windows DirectInput 컨트롤러 DIDEVICEINSTANCE에 저장된 guidProduct를 사용합니다. AK::FNVHash32 를 사용해 guidProduct를 해시 합니다.
UWP UWP 게임패드 AK::GetDeviceIDFromGamepad 를 호출해 게임패드 참조의 ID를 가져옵니다.
PlayStation 4 DUALSHOCK 4 scePadOpen 또는 scePadGetHandle에 의해 반환되는 장치의 핸들을 사용합니다.
PlayStation 4 PlayStation Move scePadOpen 또는 scePadGetHandle에 의해 반환되는 장치의 핸들을 사용합니다.
XboxOne XboxOne Controllers Use the Id stored in a IGamepad object.
Switch Joy-Con Use nn::hid::NpadId with the desired index

게임 컨트롤러는 물리적인 문제나 통신 문제로 연결이 끊어질 수 있다는 점에 유의하세요. 불필요한 리소스를 사용한다는 점 외에, 사운드 엔진에 불리한 영향을 미치지는 않습니다. 오랫동안 장치 연결이 끊어졌다고 생각되면, AK::SoundEngine::RemoveOutput 을 호출하여 이에 상응하는 AddOutput() 함수 호출로 반환된 AkOutputDeviceID 를 제공해야 합니다. 이는 리소스를 제거합니다.

멀티플레이어 고려 사항

모션 출력은 일반적인 Secondary Output과 동일하기 때문에 제한 및 요구 사항도 그와 동일합니다. 1인 플레이어 게임을 만든다는 것은 하나의 플레이어만 게임을 지역적으로 제어한다는 의미로, 리스너/게임 오브젝트 구축이 매우 간단합니다. 일반적인 경우, 새로운 모션 출력은 주요 오디오 출력에 대해 동일한 기본 Listener를 재사용하게 됩니다. 간단하게 말해서, 1인 플레이어 게임 구축에 Listener를 관리할 필요는 거의 없습니다.

멀티플레이어 게임을 만들려면, 모션 출력마다 하나씩 리스너/게임 오브젝트를 생성해줘야 합니다. 게임에 따라 각 플레이어가 각자의 햅틱 피드백을 갖게 하기 위해서입니다. 장치와 연관된 Listener는 반드시 AK::SoundEngine::AddOutput() 에 의해 해당 출력이 초기화되는 동시에 함께 초기화되어야 합니다. 지정된 Listener는 사운드나 모션을 전송하는 추가 레이어를 제공합니다. 해당 플레이어의 Listener와 고유하게 연결된 Game Object에 Event를 재생하면 특정 플레이어를 지정할 수 있습니다. 이는 AK::SoundEngine::SetListeners 를 호출하여 연결할 수 있습니다. Listener와 게임 오브젝트에 대한 더 많은 정보는 리스너 통합하기 를 확인하세요. 여러 개의 리스너를 한 게임 오브젝트로 연결할 수 있으며, 이 경우 모든 리스너에 "브로드캐스트(broadcast)" 효과가 생긴다는 점을 기억하세요.

참고: Listener Emitter가 모션 출력으로 설정되어 있다 하더라도 사운드가 모션 버스 계층 구조로 전송되어야 합니다.

예제

다음 예제는 모션을 사용하기 위해서 애플리케이션을 어떻게 구축하는지에 대한 정보를 제공합니다. SDK 예제에 포함된 Integration Demo (DemoMotion.cpp)의 Demo Motion을 참고해도 됩니다. 여기에는 지원하는 모든 플랫폼에서 대해 작동하는 예제가 나와있습니다.

단일 플레이어 구축

먼저 몇 가지 일반적인 플그러인의 관리가 필요합니다. 즉, 다른 플러그인처럼 필요한 파일을 포함시키고 해당 라이브러리를 연결해줘야 합니다. (Wwise 네이티브 개발에만 필요한 사항입니다. Unity에는 해당되지 않습니다.)

#include "AkMotionSinkFactory.h" // AkMotionSink.libAkMotionSink.lib 를 연결해 게임 객체에 출력을 구현합니다.
#include "AkMotionGeneratorSourceFactory.h" // AkMotionGenerator.lib 를 연결해 Motion Generator 소스를 구현합니다.

그런 다음 Wwise 프로젝트에 Motion ShareSet로 추가적인 출력을 추가합니다. 여기서는 'Wwise_Motion'이라는 이름을 사용합니다. 첫 번째로 연결된 게임 컨트롤러에 대해서 출력 ID로 0을 사용합니다.

AkOutputSettings outputSettings("Wwise_Motion", 0);
AK::SoundEngine::AddOutput(outputSettings);

그런 다음 평소대로 이벤트를 재생합니다. Wwise 프로젝트에서 'Play_Explosion' Event는, 특정 버스로 전송되는 Sound SFX를 가리키며, 이 버스의 Audio Device는 'Wwise_Motion' ShareSet가 할당돼있습니다.

AkGameObjectID explosionGO = 100;
AK::SoundEngine::RegisterGameObj(explosionGO, "Explosion");
AK::SoundEngine::PostEvent("Play_Explosion", explosionGO);

멀티플레이어 구축

여기에서의 멀티플레이어는 '동일한 콘솔상에서 복수의 플레이어'를 의미하며 '네트워크상에서의 멀티플레이어 게임'을 의미하지 않습니다. 멀티플레이어 시나리오에서 모션 믹스나 플레이어 전용 출력은 게임 세계 안에서 플레이어의 관점을 나타내기 위해 다르게 표현돼야 합니다. 이를 위해, 각 플레이어는 자신만의 Listener가 필요합니다.

int NUM_PLAYERS = 4;
const AkGameObjectID OBJ_FOR_PLAYER[MAX_PLAYERS] = {100 ,200, 300, 400}; // 임의의 Game Object ID를 사용합니다.
for(int i = 0; i < NUM_PLAYERS; i++)
{
AK::SoundEngine::RegisterGameObj(OBJ_FOR_PLAYER[i]); // Listener로 사용할 GameObject를 등록합니다.
AK::SoundEngine::SetListeners(OBJ_FOR_PLAYER[i], &OBJ_FOR_PLAYER[i], 1); // 직접 수신할 수 있는 Game Object를 만듭니다.
}

그런 다음 모든 플레이어에 해당되는 출력을 추가하세요. 이 때 여러 개의 ShareSets가 필요하지 않으며, 각각의 ShareSet를 여러 번 사용하면 됩니다. 모든 컨트롤러에 대한 실제 장치 ID를 제공해야 합니다. 이 예제는 Windows의 Xbox 컨트롤러를 사용합니다. 특정 플랫폼에 대한 장치 ID를 구하는 방법은 게임 구축 표를 참고하세요.

const AkUInt32 DEVICE_SPECIFIC_ID[MAX_PLAYERS] = {0, 1, 2, 3}; // Windows의 Xbox 컨트롤러에 대한 장치 ID는 간단히 0부터 3 사이 값입니다. 다른 플랫폼들은 그에 따라 다른 요구사항이 있습니다.
for(i = 0; i < NUM_PLAYERS; i++)
{
AkOutputSettings settings("Wwise_Motion", DEVICE_SPECIFIC_ID[i]); // 'Wwise_Motion' ShareSet를 사용해 장치 DEVICE_SPECIFIC_ID[i]를 다룹니다.
res = AK::SoundEngine::AddOutput(settings, &motionOutputIDs[i], &OBJ_FOR_PLAYER[i], 1); // 출력을 추가해 적절한 Listener로 연결합니다.
}

그런 다음 평소대로 이벤트를 재생합니다. Wwise 프로젝트에서 'Play_GunFire' Event는, 특정 버스로 전송되는 Sound SFX를 가리키며, 이 버스의 Audio Device는 'Wwise_Motion' ShareSet가 할당돼있습니다.

AK::SoundEngine::PostEvent("Play_GunFire", OBJ_FOR_PLAYER[0]); // Game Object-Listener 관계에 따라 플레이어 컨트롤러 0에서만 재생하게 됩니다.

여러 장치에 영향을 주는 Event를 재생하려면, 모든 플레이어 전용 Listener에 의해 수신되는 새로운 Game Object를 구축해야 합니다.

AK::SoundEngine::RegisterGameObj(explosionGO, "Explosion"); // 폭발음을 재생할 Game Object를 등록합니다.
AK::SoundEngine::SetListeners(explosionGO, OBJ_FOR_PLAYER, 4); // 플레이어의 리스너 4개 전부를 Game Object에 연결해 Motion Effect를 모두 다 받을 수 있도록 합니다.
AK::SoundEngine::PostEvent("Play_Explosion",explosionGO ); // 4개의 모든 리스너가 explosionGO에 연결되어 있기 때문에, Play_Explosion Event가 모든 게임 오브젝트에 전송됩니다.

IntegrationDemo 예제에서 DemoMotion 클래스를 참고해도 됩니다. 이 클래스는 멀티플레이어 구축 예제를 제공합니다.

확인사항 및 문제해결

하나의 장치로 모션을 받는 특정 장치를 위해서 다음 사항을 처리해야 합니다.

  • Wwise 프로젝트의 Audio Devices에 Wwise Motion ShareSet를 추가합니다.
  • 상위 레벨 Audio Bus를 생성하고 추가한 Wwise Motion에 ShareSet를 설정합니다.
  • Sound SFX를 생성하고 이를 모션 버스 계층 구조에 전송합니다.
  • 게임에서 AkMotionSink 라이브러리에 연결되도록 AkMotionSinkFactory.h를 포함해 AkMotionSink 라이브러리 연결합니다.
  • AK::SoundEngine::RegisterGameObj를 사용해서 모션 Event를 전송하고 받을 수 있게 게임 오브젝트를 생성합니다.
  • Wwise Motion ShareSet과 장치 ID로 Ak::SoundEngine::AddOutput 를 호출합니다. 멀티플레이어라면 각 플레이어에 대해 Listener 객체를 제공합니다.
  • 오디오 Event에 대해 처리하도록 같은 방식으로 Event를 트리거 합니다.

Wwise 프로젝트에서 모션을 가지려면:

  • Wwise 프로젝트의 Audio Devices에 Wwise Motion ShareSet를 추가합니다.
  • 상위 레벨 Audio Bus를 생성하고 추가한 Wwise Motion에 ShareSet를 설정합니다.
  • Sound SFX를 생성하고 이를 모션 버스 계층 구조에 전송합니다.
  • Audio Preferences에서 모션을 사용하려는 버스를 배치하고, 목록에서 해당 장치를 원하는 모션 장치로 설정합니다.

프로파일링

문제를 해결하기 위해서는 애플리케이션을 프로파일링해보시기 바랍니다. 저작 도구에서 애플리케이션을 연결하고 Profiler layout (F6)를 사용해 프로파일링할 수 있습니다. 몇몇 도구는 문제가 있는 소스코드를 이해하는 데 도움이 될 수 있습니다. Capture Log 뷰는 빨간색으로 나타나는 에러 코드를 볼 수 있게 해줍니다. Graph 뷰는 사운드 엔진 파이프라인을 시각적으로 표현해 출력합니다. 파이프라인의 마지막에서 모션 장치를 볼 수 있습니다. 그렇지 않은 경우, 사운드 엔진이 지정된 장치를 찾을 수 없다는 것을 의미합니다. 또 다른 아주 유용한 뷰로 Emitter/Listener 탭이 있습니다. 이 뷰는 모든 방사체-리스너 쌍을 보여줍니다. Motion Effect가 동작하지 않는다면, 모션 장치에 지정한 Listener로 Emitter가 연결되지 않았기 때문입니다.

Motion 효과를 트리거 했지만 작동하지 않는다면, 다음 사항을 확인하세요.

  • Capture Log에 살펴보고 플러그인에 등록 오류가 있지 않은지 확인합니다. 오류가 있다면, AkMotionSinkFactory.h를 포함하고 AkMotionSink 라이브러리에 연결했는지 확인합니다.
  • 사운드 엔진이 장치를 초기화할 수 있었는지 확인합니다. 초기화되지 않으면, 게임에서 AddOutput 가 호출될 때 Capture Log에서의 오류를 확인해야 합니다.
  • 재생하는 Sound SFX가 모션 장치로 이어지는 버스로 전송되는지 확인합니다. Sound SFX의 Audio Bus 속성과 해당 버스의 Audio Device 속성으로 확인할 수 있습니다.
  • Voices Graph 탭에서 각 Emitter의 트리거를 확인하세요. Emitter-Listener 탭에서 연결된 Listener가 있는지 확인합니다. 방사체와 리스너가 같은 게임 오브젝트일 수 있습니다. 그렇지 않다면, RegisterGameObjSetListenersAddOutput 의 호출을 확인하세요.
  • Listener가 원하는 출력 장치에 연결되었는지 확인합니다.
  • 또한 API 호출 결과를 주의 깊게 살펴보세요. 오류를 반환하는 게 없는지 확인합니다.

Android 장치에 대해서, 애플리케이션의 AndroidManifest.xml 파일에서 다음과 같은 퍼미션을 추가하는 것을 잊지 마세요.

<uses-permission android:name="android.permission.VIBRATE"/>
AKSOUNDENGINE_API AKRESULT RegisterGameObj(AkGameObjectID in_gameObjectID)
Platform-independent initialization settings of output devices.
Definition: AkSoundEngine.h:129
AKSOUNDENGINE_API AKRESULT SetListeners(AkGameObjectID in_emitterGameObj, const AkGameObjectID *in_pListenerGameObjs, AkUInt32 in_uNumListeners)
AKSOUNDENGINE_API AKRESULT AddOutput(const AkOutputSettings &in_Settings, AkOutputDeviceID *out_pDeviceID=NULL, const AkGameObjectID *in_pListenerIDs=NULL, AkUInt32 in_uNumListeners=0)
AKSOUNDENGINE_API AkPlayingID PostEvent(AkUniqueID in_eventID, AkGameObjectID in_gameObjectID, AkUInt32 in_uFlags=0, AkCallbackFunc in_pfnCallback=NULL, void *in_pCookie=NULL, AkUInt32 in_cExternals=0, AkExternalSourceInfo *in_pExternalSources=NULL, AkPlayingID in_PlayingID=AK_INVALID_PLAYING_ID)

이 페이지가 도움이 되었나요?

지원이 필요하신가요?

질문이 있으신가요? 문제를 겪고 계신가요? 더 많은 정보가 필요하신가요? 저희에게 문의해주시면 도와드리겠습니다!

지원 페이지를 방문해 주세요

작업하는 프로젝트에 대해 알려주세요. 언제든지 도와드릴 준비가 되어 있습니다.

프로젝트를 등록하세요. 아무런 조건이나 의무 사항 없이 빠른 시작을 도와드리겠습니다.

Wwise를 시작해 보세요