menu
 
버전
2021.1.14.8108

2024.1.4.8780

2023.1.12.8706

2022.1.18.8567

2021.1.14.8108

2019.2.15.7667

2019.1.11.7296

2018.1.11.6987

2017.2.10.6745

2017.1.9.6501

2016.2.6.6153

2015.1.9.5624


menu_open
Wwise Unity Integration Documentation
C# 코드를 사용하여 사운드 엔진 제어하기

대부분의 Wwise SDK 함수는 AkSoundEngine 클래스를 통해 Unity에서 사용할 수 있습니다. C++의 네임스페이스 AK::SoundEngine, AK::MusicEngine 등을 대체한다고 생각하면 됩니다. 원본 SDK와 비교하여 API 바인딩에서 변경한 내용은 API 변경 및 제한 사항 를 참고하세요. 더욱 복잡한 상황의 경우 코드에서 Wwise 함수를 호출해야 합니다. API에서 모든 함수 안에 있는 GameObjectID 는 Unity GameObject 개념으로 대체됩니다. AkGameObj 컴포넌트를 수동으로 추가지 않은 경우 런타임에서 자동으로 해당 GameObject에 추가됩니다.

Event와 Bank에 문자열이 아닌 숫자 ID 사용하기

네이티브 Wwise API에서는 문자열이나 ID를 사용하여 Wwise 프로젝트에서 이벤트나 명명된 오브젝트를 트리거할 수 있습니다. Wwise_IDs.h 파일을 Wwise_IDs.cs 로 변경하면 C::에서도 그렇게 할 수 있습니다. Assets > Wwise > Convert Wwise SoundBank IDs를 클릭하세요. 이 작업을 위해서는 Python(파이썬)이 설치되어 있어야 합니다.

Wwise에 MIDI 전송하기

AkMIDIPostArray 클래스의 AkMIDIPost 멤버를 채워 넣거나 다음 메소드를 호출하면 Wwise에 MIDI를 전송할 수 있습니다.

다음은 사운드 엔진에 MIDI 메시지를 전송하는 기본 스크립트입니다.

public class MyMIDIBehaviour : UnityEngine.MonoBehaviour
{
public AK.Wwise.Event SynthEvent;
private void Start()
{
AkMIDIPostArray MIDIPostArrayBuffer = new AkMIDIPostArray(6);
AkMIDIPost midiEvent = new AkMIDIPost();
midiEvent.byType = AkMIDIEventTypes.NOTE_ON;
midiEvent.byChan = 0;
midiEvent.byOnOffNote = 56;
midiEvent.byVelocity = 127;
midiEvent.uOffset = 0;
MIDIPostArrayBuffer[0] = midiEvent;
midiEvent.byOnOffNote = 60;
MIDIPostArrayBuffer[1] = midiEvent;
midiEvent.byOnOffNote = 64;
MIDIPostArrayBuffer[2] = midiEvent;
midiEvent.byType = AkMIDIEventTypes.NOTE_OFF;
midiEvent.byOnOffNote = 56;
midiEvent.byVelocity = 0;
midiEvent.uOffset = 48000 * 8;
MIDIPostArrayBuffer[3] = midiEvent;
midiEvent.byOnOffNote = 60;
MIDIPostArrayBuffer[4] = midiEvent;
midiEvent.byOnOffNote = 64;
MIDIPostArrayBuffer[5] = midiEvent;
SynthEvent.PostMIDI(gameObject, MIDIPostArrayBuffer);
}
}

Unity에서 오프라인 렌더링하기

Unity 통합은 Wwise SDK 안에서 오프라인 렌더링하기 기능을 제공하여 오디오 샘플을 가져올 수 있는 방법을 간소화해줍니다.

warning 주의: 오프라인 렌더링이 활성화된 경우 비동기적 AkSoundEngine.LoadBankAkSoundEngine.UnloadBank API만 메인 스레드에서 사용되도록 주의해야 합니다. 더 자세한 설명은 오디오 렌더링 커스텀 예약을 참고해 주세요.

AkSoundEngine.StartDeviceCapture 는 캡처를 위해 특정 출력 오디오 장치를 설정하여 AkSoundEngine.UpdateCaptureSampleCount 를 호출해서 사용 가능한 샘플의 개수를 결정하고 AkSoundEngine.GetCaptureSamples 를 사용하여 오디오 샘플을 가져올 수 있도록 해줍니다.

다음 예시는 Unity의 스크린 캡처 기능과 함께 Unity 통합을 사용하여 오프라인 오디오 렌더링을 실행하는 방법을 설명해줍니다. 이 기능이 구현됨으로써 다중 조작 후반 처리 단계를 쉽게 실행하여 캡처된 오디오 샘플과 비디오 프레임을 동영상으로 조합할 수 있게 되었습니다.

public abstract class WwiseOfflineRenderer : UnityEngine.MonoBehaviour
{
public bool IsOfflineRendering { get; set; }
public bool StartWithOfflineRenderingEnabled = false;
private bool IsCurrentlyOfflineRendering = false;
public float FrameRate = 25.0f;
protected ulong OutputDeviceId = 0;
public abstract string GetUniqueScreenshotFileName(int frameCount);
public abstract void ProcessAudioSamples(float[] buffer);
protected void Start()
{
OutputDeviceId = AkSoundEngine.GetOutputID(AkSoundEngine.AK_INVALID_UNIQUE_ID, 0);
if (StartWithOfflineRenderingEnabled)
{
IsOfflineRendering = true;
Update();
}
}
private void LogAudioFormatInfo()
{
var sampleRate = AkSoundEngine.GetSampleRate();
var channelConfig = new AkChannelConfig();
var audioSinkCapabilities = new Ak3DAudioSinkCapabilities();
AkSoundEngine.GetOutputDeviceConfiguration(OutputDeviceId, channelConfig, audioSinkCapabilities);
UnityEngine.Debug.LogFormat("Sample Rate: {0}, Channels: {1}", sampleRate, channelConfig.uNumChannels);
}
protected void Update()
{
if (IsOfflineRendering != IsCurrentlyOfflineRendering)
{
IsCurrentlyOfflineRendering = IsOfflineRendering;
if (IsOfflineRendering)
{
#if UNITY_EDITOR
// 에디터 업데이트가 AkSoundEngine.RenderAudio()를 호출하지 않도록 확인하세요.
AkSoundEngineController.Instance.DisableEditorLateUpdate();
#endif
LogAudioFormatInfo();
AkSoundEngine.ClearCaptureData();
AkSoundEngine.StartDeviceCapture(OutputDeviceId);
}
else
{
AkSoundEngine.StopDeviceCapture(OutputDeviceId);
#if UNITY_EDITOR
// 에디터 업데이트 호출을 AkSoundEngine.RenderAudio()로 다시 가져옵니다.
AkSoundEngineController.Instance.EnableEditorLateUpdate();
#endif
}
}
var frameTime = IsOfflineRendering && FrameRate != 0.0f ? 1.0f / FrameRate : 0.0f;
UnityEngine.Time.captureDeltaTime = frameTime;
AkSoundEngine.SetOfflineRenderingFrameTime(frameTime);
AkSoundEngine.SetOfflineRendering(IsOfflineRendering);
if (!IsOfflineRendering)
return;
UnityEngine.ScreenCapture.CaptureScreenshot(GetUniqueScreenshotFileName(UnityEngine.Time.frameCount));
var sampleCount = AkSoundEngine.UpdateCaptureSampleCount(OutputDeviceId);
if (sampleCount <= 0)
return;
var buffer = new float[sampleCount];
var count = AkSoundEngine.GetCaptureSamples(OutputDeviceId, buffer, (uint)buffer.Length);
if (count <= 0)
return;
ProcessAudioSamples(buffer);
}
}

Unity에서 오디오 입력 음원 플러그인 사용하기

오디오 입력 음원 플러그인은 C# 스크립트를 통해 사용할 수 있습니다. Wwise SDK 설명서에서 오디오 입력 음원 플러그인을 참고하세요.

다음은 오디오 입력 음원 플러그인에 시험음을 전송하는 기본 스크립트입니다.

public class MyAudioInputBehaviour : UnityEngine.MonoBehaviour
{
public AK.Wwise.Event AudioInputEvent;
public uint SampleRate = 48000;
public uint NumberOfChannels = 1;
public uint SampleIndex = 0;
public uint Frequency = 880;
private bool IsPlaying = true;
// 오디오 샘플을 채워 넣는 콜백 - 이 함수는 모든 채널에 대해서 각 프레임마다 호출됩니다.
bool AudioSamplesDelegate(uint playingID, uint channelIndex, float[] samples)
{
for (uint i = 0; i < samples.Length; ++i)
samples[i] = UnityEngine.Mathf.Sin(Frequency * 2 * UnityEngine.Mathf.PI * (i + SampleIndex) / SampleRate);
if (channelIndex == NumberOfChannels - 1)
SampleIndex = (uint)(SampleIndex + samples.Length) % SampleRate;
// false를 반환하여 제공할 데이터가 없음을 표시합니다. 이 경우 연결된 이벤트도 중단됩니다.
return IsPlaying;
}
// 오디오 형식을 설정하는 콜백 - 이 함수는 샘플이 요청되기 전에 한 번 호출됩니다.
void AudioFormatDelegate(uint playingID, AkAudioFormat audioFormat)
{
// 설정해야 하는 주요 매개 변수는 채널 구성과 샘플 레이트입니다.
audioFormat.channelConfig.uNumChannels = NumberOfChannels;
audioFormat.uSampleRate = SampleRate;
}
private void Start()
{
// Audio Input 플러그인을 사용하도록 Wwise 안에서 설정된 AudioInputEvent 이벤트는 gameObject에 전달됩니다.
// AudioFormatDelegate는 한 번 호출되며 AudioSamplesDelegate는 false를 리턴할 때까지 각 프레임마다 한 번 호출됩니다.
AkAudioInputManager.PostAudioInputEvent(AudioInputEvent, gameObject, AudioSamplesDelegate, AudioFormatDelegate);
}
// 이 메소드를 다른 스크립트에서 호출하여 콜백을 중단할 수 있습니다
public void StopSound()
{
IsPlaying = false;
}
private void OnDestroy()
{
AudioInputEvent.Stop(gameObject);
}
}

Unity에서 맞춤 위치 지정 적용하기

기본적으로 AkGameObj 컴포넌트는 특정한 Unity gameObject 에 연결되어 있으며 트랜스폼(transform) (필요시 상쇄값도 포함)을 사용하여 전체 위치 지정을 설정합니다. 이 방법은 보통 1인칭 슈팅 게임과 같은 수많은 게임에 적합합니다. 하지만 3인칭 게임과 같이 맞춤 카메라 각도가 있는 게임의 경우, Unity의 메인 카메라와 같이 한 게임 오브젝트에 오디오 리스너(audio listener)를 연결해서는 위치 지정의 두 방면 (거리 감쇠와 공간화)를 다루기가 어렵습니다. 게임에 따라 플레이어가 맞춤화된 다른 위치 지정을 경험하도록 하고자 할 수 있습니다.

이런 경우를 위해 AkGameObj 컴포넌트 클래스는 Unity 사용자가 위치 지정을 오버라이드할 수 있게 해줍니다. Unity에서는 세 가지 가상 메소드인 GetPosition(), GetForward(), GetUpward() 를 통해 AkGameObj 로부터 하위 클래스를 만들고, 이 하위 클래스 컴포넌트를 사용해서 Unity gameObjects 의 위치 지정을 맞춤화할 수 있습니다.

다음은 커스텀 컴포넌트를 사용하여 기본 AkAudioListener 작동 방식을 덮어쓰는 방법을 보여주는 간단한 예시입니다. Wwise를 사용하여 통합된 3인칭 프로젝트의 경우 기존의 AkAudioListener 와 연관된 AkGameObj 를 제거하세요. 그리고 다음 스크립트를 MainCamera 오브젝트에 연결하고 AkAudioListener 를 연결하세요. 마지막으로 오디오 리스너의 위치가 따를 대상 Unity gameObject (예를 들어 플레이어 아바타와 같이)를 지정하세요. 이렇게 하면 모든 방사체의 거리 감쇠가 선택된 Unity gameObject 의 위치를 청자의 위치 (화면 안의 거리 리스너)로 사용하며, 모든 방사체의 거리는 여전히 메인 카메라의 방향을 청자의 방향 (화면 밖의 방향 리스너)으로 설정합니다.

#if ! (UNITY_DASHBOARD_WIDGET || UNITY_WEBPLAYER || UNITY_WII || UNITY_WIIU || UNITY_NACL || UNITY_FLASH || UNITY_BLACKBERRY) // Disable under unsupported platforms.
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2023 Audiokinetic Inc.
*/
using UnityEngine;
using System;
using System.Collections.Generic;
[AddComponentMenu ("Wwise/AkGameObj3rdPersonCam")]
[ExecuteInEditMode] //isStaticObject의 알맞은 상태를 유지하는 데 필요한 ExecuteInEditMode입니다.
public class AkGameObj3rdPersonCam : AkGameObj
{
public Transform target; // 해당 카메라가 따라갈 위치를 말합니다. 인스펙터에서 사용자가 이 부분을 플레이어 캐릭터의 Unity gameObject로 지정할 수 있습니다.
// 카메라의 위치를 플레이어의 위치로 설정하여 거리 감쇠를 처리합니다.
public override Vector3 GetPosition ()
{
return target.GetComponent<AkGameObj> ().GetPosition ();
}
}
#endif // #if ! (UNITY_DASHBOARD_WIDGET || UNITY_WEBPLAYER || UNITY_WII || UNITY_WIIU || UNITY_NACL || UNITY_FLASH || UNITY_BLACKBERRY) // Disable under unsupported platforms.
Definition: AkWwiseAcousticTexture.cs:20
This type can be used to post Events to the sound engine.
Definition: AkWwiseEvent.cs:28
This component represents a sound object in your scene tracking its position and other game syncs suc...
Definition: AkGameObj.cs:32
Definition: AkWwiseAcousticTexture.cs:20
virtual UnityEngine.Vector3 GetPosition()
Definition: AkGameObj.cs:221

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

지원이 필요하신가요?

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

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

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

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

Wwise를 시작해 보세요