이 문서에서는 Unity 5.0에 빌트인된 네이티브 오디오 플러그인 인터페이스에 대해 설명합니다. 여기서는 뒤로 갈수록 점점 복잡해지는 구체적인 플러그인의 예제를 살펴보는 방식으로 매우 기초적인 개념부터 시작하여 문서의 끝부분에서는 더 복잡한 이용 사례를 소개합니다.
가장 먼저 해야할 일은 가장 최신 오디오 플러그인 SDK를 다운로드하는 것입니다.
네이티브 오디오 플러그인 시스템은 다음 두 부분으로 구성됩니다.
C나 C++로 작성된 .dll(Windows) 또는 .dylib(OSX)로 구현되어야 하는 네이티브 DSP(디지털 시그널 프로세싱) 플러그인. 스크립트와 달리, 이 플러그인에는 높은 성능이 요구되기 때문에 지원할 플랫폼에 대해 컴파일해야 하고 플랫폼별 최적화가 필요할 수 있습니다.
C#으로 개발된 GUI. GUI는 선택 사항이므로 항상 기본 네이티브 DSP 플러그인을 만들어 플러그인 개발을 시작하고, Unity가 네이티브 플러그인이 노출시키는 파라미터 설명에 대한 기본 슬라이더 기반 UI를 표시하도록 해야 합니다. 이 방법은 프로젝트를 부트스트랩하는 데 권장됩니다.
다른 에디터 스크립트와 마찬가지로, 처음에는 Assets/Editor 폴더에 간단히 저장하는 .cs 파일로 C# GUI의 프로토타입을 만들 수 있습니다. 이후에 코드가 규모가 커지면서 모듈화와 IDE 지원을 개선해야 할 때 이 파일을 적절한 Visual Studio 프로젝트로 옮길 수 있습니다. 그러면 이 파일을 .dll로 컴파일할 수 있으므로 사용자가 이 파일을 프로젝트에 더 쉽게 포함시키고 코드를 보호할 수도 있습니다.
또한 네이티브 DSP와 GUI DLL은 모두 다수의 플러그인을 포함할 수 있고, 바인딩은 DLL파일 이름에 상관 없이 플러그인의 효과 이름에 따라서만 수행됩니다.
플러그인 SDK의 네이티브 쪽은 실제로 파일 하나(AudioPluginInterface.h)로만 구성되지만, 동일 DLL 안에 다수의 플러그인 효과를 쉽게 포함시킬 수 있도록 효과 정의와 파라미터 등록을 간단하고 통일된 방법으로 처리하는 지원 코드가 추가되었습니다(AudioPluginUtil.h와 AudioPluginUtil.cpp). NativePluginDemo 프로젝트에는 시작할 때 사용할 수 있고 게임 컨텍스트에서 유용한 여러 다양한 플러그인 타입을 보여주는 다수의 플러그인 예제가 포함되어 있습니다. 이 코드는 공용 도메인에 무료로 공개되므로, 이 코드를 창착물의 출발점으로 자유롭게 사용합니다.
플러그인 개발은 플러그인에 포함되어야 하는 파라미터를 정하여 시작합니다. 시작하기 전에 플러그인에 포함될 모든 파라미터의 상세한 마스터플랜이 있어야 할 필요는 없지만, 향후 사용자에게 어떤 경험을 제공하고 싶고 어떤 컴포넌트가 필요할지 대략적인 계획이 있으면 도움이 됩니다.
Unity에서 제공하는 예제 플러그인에는 사용 편리성을 위한 여러 유틸리티 기능이 있습니다. “Ring Modulato” 예제 플러그인을 살펴보겠습니다. 이 간단한 플러그인은 수신 신호를 사인파와 곱함으로써, 특히 주파수가 서로 다른 여러 링 모듈레이션 효과가 체인처럼 연결된 경우 전파 잡음/수신 끊김과 유사한 효과를 주게 됩니다.
예제 플러그인에서 파라미터를 처리하는 기본적인 방법은 편리성과 간결성을 위해 사용하는 열거형 값을 실수 배열의 인덱스로 정의하는 것입니다.
enum Param
{
P_FREQ,
P_MIX,
P_NUM
};
int InternalRegisterEffectDefinition(UnityAudioEffectDefinition& definition)
{
int numparams = P_NUM;
definition.paramdefs = new UnityAudioParameterDefinition [numparams];
RegisterParameter(definition, "Frequency", "Hz",
0.0f, kMaxSampleRate, 1000.0f,
1.0f, 3.0f,
P_FREQ);
RegisterParameter(definition, "Mix amount", "%",
0.0f, 1.0f, 0.5f,
100.0f, 1.0f,
P_MIX);
return numparams;
}
RegisterParameter 호출에서의 숫자는 최소값, 최대값 및 기본값에 이은 표시에만 사용되는 스케일링 계수입니다. 예를 들어, 백분율 값의 경우 실제 값은 0에서 1까지 증가하지만 표시할 때는 100으로 곱합니다. 여기에 사용되는 커스텀 GUI 코드는 없지만, 앞서 언급한 바와 같이 Unity는 이런 기본 파라미터 정의로부터 기본 GUI를 생성합니다. 정의되지 않은 파라미터에 대해서는 확인 절차가 수행되지 않으므로, AudioPluginUtil 시스템은 모든 선언된 열거값(P_NUM
제외)이 상응하는 파라미터 정의와 일치할 것이라고 예상합니다.
보이지 않는 곳에서 RegisterParameter 함수는 해당 플러그인과 연관된 UnityAudioEffectDefinition 구조의 UnityAudioParameterDefinition 배열에 엔트리를 채워 넣습니다(“AudioEffectPluginInterface.h” 참조). UnityAudioEffectDefinition에서 설정해야 하는 나머지 항목은 플러그인 인스턴스화(CreateCallback), 파라미터 설정/가져오기(SetFloatParameterCallback/UnityAudioEffect_GetFloatParameterCallback
), 실제 프로세스 수행(UnityAudioEffect_ProcessCallback
) 및 이후 완료 시 플러그인 인스턴스 파괴(UnityAudioEffect_ReleaseCallback
)를 처리하는 함수에 대한 콜백입니다.
동일 DLL 안에 여러 플러그인을 쉽게 포함시킬 수 있도록 각 플러그인은 자체 네임스페이스에 있고, DEFINE_EFFECT
및 DECLARE_EFFECT
매크로가 UnityAudioEffectDefinition 구조를 채울 수 있도록 콜백 함수에 대한 구체적인 명명 규칙이 사용됩니다. 보이지 않는 곳에서 모든 효과 정의는 UnityGetAudioEffectDefinitions 라이브러리의 유일한 엔트리 포인트에 의해 포인터가 반환되는 배열에 저장됩니다.
위 내용은 VST나 AudioUnits 등 다른 포맷의 플러그인에서 Unity 오디오 플러그인 인터페이스로 매핑하는 브릿지 플러그인을 개발하려고 할 때 알아두면 유용합니다. 이 경우 로드 시간에 파라미터 설명을 설정하는 보다 동적인 방식을 개발해야 합니다.
다음은 플러그인 인스턴스에 대한 데이터입니다. 예제 플러그인에서는 모든 데이터를 EffectData 구조에 넣습니다. 데이터는 믹서의 각 플러그인 인스턴스에 대해 호출되는 해당 CreateCallback에서 할당되어야 합니다. 이 간단한 예에는 모든 채널에 곱해지는 사인파가 하나뿐이지만, 그 외에 더 고급의 플러그인은 입력 채널당 추가 데이터를 할당해야 합니다.
struct EffectData
{
struct Data
{
float p[P_NUM]; // Parameters
float s; // Sine output of oscillator
float c; // Cosine output of oscillator
};
union
{
Data data;
unsigned char pad[(sizeof(Data) + 15) & ~15];
};
};
UNITY_AUDIODSP_RESULT UNITY_AUDIODSP_CALLBACK CreateCallback(
UnityAudioEffectState* state)
{
EffectData* effectdata = new EffectData;
memset(effectdata, 0, sizeof(EffectData));
effectdata->data.c = 1.0f;
state->effectdata = effectdata;
InitParametersFromDefinitions(
InternalRegisterEffectDefinition, effectdata->data.p);
return UNITY_AUDIODSP_OK;
}
UnityAudioEffectState는 샘플링 속도, (시간당) 처리된 전체 샘플 수, 또는 플러그인의 바이패스 여부 등 호스트에서 전송된 다양한 데이터를 포함하고 모든 콜백 함수로 전달됩니다.
또한 플러그인 인스턴스를 해제하기 위한 함수도 있습니다.
UNITY_AUDIODSP_RESULT UNITY_AUDIODSP_CALLBACK ReleaseCallback(
UnityAudioEffectState* state)
{
EffectData::Data* data = &state->GetEffectData<EffectData>()->data;
delete data;
return UNITY_AUDIODSP_OK;
}
오디오 메인 프로세싱은 ProcessCallback에서 수행됩니다.
UNITY_AUDIODSP_RESULT UNITY_AUDIODSP_CALLBACK ProcessCallback(
UnityAudioEffectState* state,
float* inbuffer, float* outbuffer,
unsigned int length,
int inchannels, int outchannels)
{
EffectData::Data* data = &state->GetEffectData<EffectData>()->data;
float w = 2.0f * sinf(kPI * data->p[P_FREQ] / state->samplerate);
for(unsigned int n = 0; n < length; n++)
{
for(int i = 0; i < outchannels; i++)
{
outbuffer[n * outchannels + i] =
inbuffer[n * outchannels + i] *
(1.0f - data->p[P_MIX] + data->p[P_MIX] * data->s);
}
data->s += data->c * w; // cheap way to calculate a sine-wave
data->c -= data->s * w;
}
return UNITY_AUDIODSP_OK;
}
상단의 GetEffectData 함수는 상태 변수의 effectdata 필드를 위에 선언한 구조체의 EffectData::Data에 캐스트하는 헬퍼 함수일 뿐입니다.
그 외에 입력 신호에 가변 주파수의 백색 소음을 더하거나 곱하는 NoiseBox 플러그인이나 신호를 간단히 다운샘플링하거나 양자화하는 Lofinator 플러그인 같은 간단한 플러그인이 있습니다. 이 플러그인을 모두 서로 조합하거나 게임 기반 에니메이션 파라미터와 함께 사용하여 휴대폰에서 무전기의 무선 수신 불량이나 망가진 스피커 등에 이르는 모든 것을 시뮬레이션할 수 있습니다.
StereoWidener는 스테레오 입력 신호를 가변 지연이 있는 모노 및 사이드 컴포넌트로 분해한 다음 다시 결합하여 인지되는 스테레오 효과를 증가시킵니다.
네이티브 오디오 플러그인은 플러그인 임포터 인스펙터를 통해 각 플랫폼과 연결해야 한다는 점에서 다른 네이티브 또는 관리되는 플러그인과 동일한 방법을 사용합니다. 플러그인을 저장할 하위 폴더에 대한 자세한 내용은 여기에서 확인할 수 있습니다. 스탠드얼론 빌드에서 각 빌드 타켓에 포함시킬 플러그인을 시스템이 알아야 하기 때문에 플랫폼 연계가 필요하며, 64비트 지원이 도입됨에 따라 플랫폼 안에서도 연계를 지정해야 합니다. 이런 면에서 OSX 플러그인은 유니버설 바이너리 포맷으로 인해 동일한 번들에 32비트 및 64비트 배리언트가 포함될 수 있기 때문에 특별합니다.
관리되는 코드에서 호출되는 Unity의 네이티브 플러그인은 네이티브 DLL에서 임포트할 함수를 참조하는 [DllImport] 속성을 통해 로드됩니다. 하지만 네이티브 오디오 플러그인의 경우는 다릅니다. 이 경우에는 플러그인의 효과를 필요로 할 수 있는 믹서 에셋을 생성하기 전에 오디오 플러그인이 로드되어야 한다는 문제가 발생합니다. 에디터에서는 간단히 플러그인에 종속하는 믹서를 다시 로드하고 다시 빌드할 수 있기 때문에 문제가 되지 않지만, 스탠드얼론 빌드에서는 믹서 에셋을 만들기 전에 플러그인이 로드되어야 합니다. 이 문제를 해결하기 위해, 현행 규칙에서는 플러그인의 DLL 앞에 “audioplugin”(대소문자 구분하지 않음)을 추가하여 시스템이 이 플러그인을 인식하고 시작 시에 자동으로 로드되는 플러그인 리스트에 추가하도록 규정하고 있습니다. 플러그인 내 정의만 Unity 믹서 안에 표시되는 효과 이름을 정의하므로 DLL의 이름은 무엇이든 상관 없지만, “audioplugin” 문자열로 시작해야만 올바르게 인식된다는 점을 명심하시기 바랍니다.
iOS 같은 플랫폼에서, 플러그인 코드는 생성된 XCode 프로젝트에서 제작된 Unity 바이너리에 정적으로 연결되어야 하고 거기서 플러그인 렌더링 디바이스와 마찬가지로 플러그인 등록을 앱의 시작 코드에 명시적으로 추가해야 합니다.
OSX에서는 번들 하나에 플러그인의 32비트와 64비트 버전이 모두 포함될 수 있습니다. 크기를 줄이기 위해 버전을 나눌 수도 있습니다.
이제 좀 더 고급 이퀄라이제이션 및 멀티밴드 압축 효과에 대해 알아보겠습니다. 이런 플러그인에는 이전 섹션에서 본 단순 플러그인보다 훨씬 더 많은 수의 파라미터가 있고, 파라미터 간에 어느 정도의 물리적인 연결도 있어 여러 단순 슬라이더보다 파라미터를 시각화할 방법이 요구됩니다. 이퀄라이저를 예로 들면, 각 밴드에는 마지막 이퀄라이제이션 커브에 영향을 주는 3가지 필터가 있고, 각 필터에는 물리적으로 연결되고 각 필터의 모양을 정의하는 3개의 파라미터인 주파수, Q인자 및 게인이 있습니다. 따라서 사용자에게 큰 도움이 되며 만약 이퀄라이저 플러그인에 개별 필터의 기여도를 의미하는 결과 커브를 보여주는 크고 멋진 디스플레이가 있다면 동시에 변하는 슬라이더 대신에 컨트롤에서 단순한 드래깅 작업에 의해 다수의 파라미터가 동시에 설정되는 방식으로 작동할 수 있습니다.
이퀄라이저 플러그인의 커스텀 GUI. 필터 커브의 게인과 주파수를 변경하려면 세 밴드를 드래그합니다. 각 밴드의 모양을 변경하려면 드래그하는 동안 shift를 길게 누릅니다.
따라서 이 경우에도 정의, 초기화, 초기화 해제 및 파라미터는 단순 플러그인에 사용되는 것과 똑같은 열거형(ENUM) 메서드에 따라 처리되며, ProcessCallback 코드도 짧은 편입니다. 이제 네이티브 코드를 충분히 살펴보았으니 Visual Studio에서 AudioPluginDemoGUI.sln 프로젝트를 열어봐야 합니다. 여기서 GUI 코드의 관련 C# 클래스를 찾을 수 있습니다. 작동 방식은 간단합니다. Unity는 네이티브 플러그인 DLL을 로드하고 포함된 오디오 플러그인을 등록한 후 등록된 플러그인의 이름과 일치하는 해당 GUI를 찾아보기 시작합니다. 이 작업은 모든 커스텀 플러그인 GUI와 마찬가지로 IAudioEffectPluginGUI로부터 상속되어야 하는 EqualizerCustomGUI 클래스의 이름 프로퍼티를 통해 수행됩니다. 이 클래스 안에 있는 중요한 함수는 bool OnGUI(IAudioEffectPlugin 플러그인) 함수 뿐입니다. 이 함수는 IAudioEffectPlugin 플러그인 인수를 통해 네이티브 플러그인에서 정의한 파라미터를 읽고 쓰는 데 사용할 수 있는 네이티브 플러그인의 핸들을 가져옵니다. 따라서 파라미터를 읽기 위해 다음을 호출합니다.
plugin.GetFloatParameter("MasterGain", out masterGain);
파라미터를 찾으면 참값을 반환합니다. 설정하려면 다음을 호출합니다.
plugin.SetFloatParameter("MasterGain", masterGain);
이 경우에도 파라미터가 존재하면 참값을 반환합니다. 이는 근본적으로 GUI와 네이티브 코드 사이의 가장 중요한 바인딩입니다. 다음 함수를 사용하여
plugin.GetFloatParameterInfo("NAME", out minVal, out maxVal, out defVal);
“NAME” 파라미터의 최소, 최대 및 기본값을 쿼리하여 네이티브 및 UI 코드에서 이들 값의 정의가 중복되지 않도록 할 수 있습니다. OnGUI 함수에서 참값을 반환하면 인스펙터의 커스텀 GUI 아래에 기본 UI 슬라이더가 표시됩니다. 이 인스펙터 또한 커스텀 GUI를 개발하는 동안 사용할 수 있는 모든 파라미터가 있고 이에 대한 올바른 동작이 원하는 파라미터 변화로 이어지는지 쉽게 확인하는 방식이 있기 때문에 GUI 개발을 부트스트랩하는 데 유용합니다.
여기서는 이퀄라이저 및 멀티밴드 플러그인에서 실행되는 DSP 프로세싱에 대해 자세히 설명하지 않습니다. 참고로 필터는 Robert Bristow Johnson의 훌륭한 오디오 EQ 쿡북에서 가져온 것이며, 곡선을 그리기 위해 Unity는 주파수 응답에 대한 안티앨리어싱된 곡선을 그리는 내부 API 함수를 몇 가지 제공합니다.
하지만 한 가지 더 언급하자면, 이퀄라이저와 멀티밴드 플러그인 모두 플러그인의 효과를 시각화하기 위해 입력 및 출력 스펙트럼을 오버레이할 코드도 제공하여 다음과 같은 흥미로운 문제를 제기합니다. GUI 코드는 오디오 프로세싱보다 훨씬 더 느린 업데이트 속도(프레임 속도)로 실행되고 오디오 스트림에 액세스할 수 없는데, 그러면 어떻게 이 데이터를 읽어야 할까요? 이 문제를 해결하기 위해 네이티브 코드에 이를 위한 특별한 함수가 있습니다.
UNITY_AUDIODSP_RESULT UNITY_AUDIODSP_CALLBACK GetFloatParameterCallback(
UnityAudioEffectState* state,
int index,
float* value,
char *valuestr)
{
EffectData::Data* data = &state->GetEffectData<EffectData>()->data;
if(index >= P_NUM)
return UNITY_AUDIODSP_ERR_UNSUPPORTED;
if(value != NULL)
*value = data->p[index];
if(valuestr != NULL)
valuestr[0] = 0;
return UNITY_AUDIODSP_OK;
}
이 함수를 사용하면 간단히 네이티브 플러그인으로부터 플로팅 포인트 데이터 배열을 읽어올 수 있습니다. 어떤 데이터든 요청으로 인해 UI나 네이티브 코드가 심각하게 느려지지 않는 이상 플러그인 시스템은 변화하지 않습니다. 이퀄라이저 및 멀티밴드 코드에는 플러그인의 입력 및 출력 데이터를 주입하고 스펙트럼을 회수하는 작업을 용이하게 하는 FFTAnalyzer라는 유틸리티 클래스가 있습니다. 이 스펙트럼 데이터는 GetFloatBufferCallback에 의해 리샘플링되고 C# UI 코드에 전달됩니다. 데이터를 리샘플링해야 하는 이유는 GetFloatBufferCallback이 데이터가 표시되는 뷰의 너비에 의해 정해지는 요청된 샘플 수만반환하는 반면 FFTAnalyzer가 고정 주파수 해상도에서 분석을 실행하기 때문입니다. 최소량의 DSP 코드가 있는 각 단순한 플러그인에 대해서는 신호가 “얼마나 입체음향적”인지 나타내기 위해 오른쪽 채널의 진폭을 왼쪽 채널의 진폭과 대조하여 표시하는 CorrelationMeter 플러그인도 참조할 수 있습니다.
왼쪽: CorrelationMeter 플러그인의 커스텀 GUI
오른쪽: 오버레이된 스펙트럼 분석 이퀄라이저 GUI(초록색 커브는 소스, 빨간색 곡선은 처리된 것임)
이퀄라이저와 멀티밴드 효과가 모두 의도적으로 단순하고 최적화되지 않은 상태로 유지되지만 플러그인 시스템이 지원하는 더 복잡한 UI의 좋은 예이기도 하다는 점을 강조하고자 합니다. 여전히 관련 플랫폼별 최적화를 수행하는 일과 완벽하다고 느껴지도록, 또한 가장 음악적인 방식으로 반응하도록 무수한 파라미터를 조정하는 일 등에는 해결할 과제가 많이 있습니다. 단순히 Unity의 표준 플러그인 리스트를 늘리기 편하도록 언젠가 이와 같은 효과를 Unity 빌트인 플러그인으로 지정할 수도 있습니다. 사용자도 정말로 멋진 플러그인을 만드는 도전을 해볼 수 있습니다. 그 플러그인이 언젠가 빌트인 플러그인이 될 수도 있습니다.
컨볼루션 리버브 플러그인의 예. 임펄스 응답은 감쇠되는 임의 노이즈로 파라미터에 따라 정의됩니다. 이 플러그인은 시연 용도로만 제공됩니다. 프로덕션 플러그인으로 사용하려면 사용자가 임의로 녹음된 임펄스를 로드할 수 있어야 합니다. 그러나 근본적인 컨볼루션 알고리즘은 동일합니다.
3개의 서로 다른 타임 스케일에서 레벨을 측정하는 소리 크기 모니터링 툴의 예. 마찬가지로 시연용이지만 최신 소리 크기 표준화를 준수하는 모니터링 툴을 빌드하기 시작하는 데 유용합니다. 커브 렌더링 코드는 Unity에 내장되어 있습니다.
이제 직접 한번 해보겠습니다. 프로세싱만 하기보다는 플러그인 시스템을 사용해 사운드를 생성해 보는게 어떻습니까? 애시드 트랜스 음악을 듣는 사람들에게 익숙한 몇 가지 심플한 베이스라인과 드럼 신시사이저를 써 보도록 하겠습니다. 이 장르를 대표하는 메인 신시사이저의 간단한 클론을 사용합니다. Plugin_TeeBee.cpp와 Plugin_TeeDee.cpp를 보면 이 간단한 신시사이저에는 임의의 음으로 패턴을 생성하고 합성 엔진에서 필터 및 엔벨로프 등을 미세 조정하는 파라미터도 있습니다. 이에 대해서도 역시 여기서는 자세한 내용을 거론하지 않겠지만, state->dsptick 파라미터가 “song”에서 위치를 결정하기 위해 ProcessCallback에서 읽힌다는 점을 주목하시기 바랍니다. 이 카운터는 전반적인 샘플 포지션이기 때문에 샘플에 명시된 각 음의 길이로 나누고, 나누어 떨어질 때마다 합성 엔진에 이벤트를 발생시킵니다. 이렇게 모든 플러그인 효과가 동일한 샘플 기반의 클럭으로 싱크되며 예를 들어 그런 효과를 통해 알려진 템포에 미리 녹음된 음악을 재생하면 템포 동기화된 필터 효과나 음악의 딜레이에 적용하는 데 타이밍 정보를 활용할 수 있습니다.
네이티브 오디오 플러그인 SDK는 오디오 소스에 따라 인스턴스화되는 커스텀 공간화 효과를 개발하는 데 사용할 수 있는 공간화 SDK의 기초입니다. 이에 대한 자세한 정보는 여기에서 확인할 수 있습니다.
네이티브 오디오 플러그인 SDK는 고성능 네이티브 코드에 사운드 시스템 일부를 개발하기 위한 첫걸음에 불과합니다. Unity는 이를 Unity의 다른 부분에 통합하여 믹서 외에 다른 곳에서 사용할 수 있는 효과를 만들 계획입니다. 또한 바이너리 데이터의 스토리지뿐만 아니라 기본 GUI를 보다 더 지원하여 float 이외의 다른 파라미터 타입을 지원하기 위해 SDK를 확대할 계획도 구상하고 있습니다.
자신만의 플러그인을 직접 제작해 보십시오. 직접 만든 플러그인을 에셋 스토어에서 볼 수 있길 바랍니다.
디자인에는 많은 유사점이 있지만, Unity의 네이티브 오디오 SDK는 Steinberg VST나 Apple AudioUnits 등 다른 플러그인 SDK를 바탕으로 빌드되지 않았습니다. 이 SDK를 사용하여 이런 플러그인을 Unity에서 사용할 수 있도록 기본 래퍼를 쉽게 구현할 수는 있습니다. 하지만 Unity 개발팀에서는 이에 대한 계획이 없습니다. 플러그인을 제대로 호스팅하려면 매우 복잡하며, 예상되는 모든 호출 순서의 복잡성에 대처하고 네이티브 코드를 기반으로 하는 커스텀 GUI 창을 다루는 일은 매우 빨리 변화하기 때문에 예제 코드로서의 유용성이 떨어집니다.
VST 또는 AU 플러그인이나 심지어는 효과를 단순히 사운드 디자인을 모형으로 만들거나 테스트하기 위해 로드하면 꽤 유용할 수 있지만, VST/AU를 사용하면 몇 개의 특정 플랫폼으로만 제한된다는 사실을 명심해야 합니다. Unity SDK를 기반으로 오디오 플러그인을 작성하면 소프트웨어 믹싱과 동적으로 로드되는 네이티브 코드를 지원하는 모든 플랫폼으로 확장될 수 있습니다. 하지만 커스텀 플러그인을 개발하는 데 (또는 단순히 어떤 식으로도 사운드를 수정하지 않는 에디터에서 미터링 플러그인을 사용할 수 있도록 하는 데)시간을 할애하기 전, 선호하는 툴로 사운드 디자인 초기모형을 만드는데 유용한 이용 사례가 있으므로, 누구라도 멋진 솔루션을 만들 수 있습니다.
2018–03–19 페이지 수정됨
2018.1에서 MonoDevelop는 Visual Studio로 교체됨