이 튜토리얼에서는 Unity에서 오디오 파일을 재생하는 방법과, 특히 Audio Source에서 오디오가 겹쳐 재생되는 문제를 제가 어떻게 해결했는지 보여드리겠습니다.


이 튜토리얼의 동영상 버전은 현재 이 언어로 제공되지 않습니다.


영상 자막 텍스트

안녕하세요 여러분! 이 튜토리얼에서는 Unity에서 오디오 파일을 재생하는 방법과, 특히 Audio Source에서 오디오가 겹쳐 재생되는 문제를 제가 어떻게 해결했는지 보여드리겠습니다. 진행하기 전에 한 가지 말씀드리면, 영상에서 소개하는 해결 방법은 이 문제에 대해 제가 선택한 방식일 뿐이며, 다른 더 나은 해결 방법도 있을 수 있습니다. 따라서 여기 제공되는 내용을 유일한 정답으로 받아들이지는 마세요.

이 튜토리얼은 Unity 2022를 사용하여 제작되었습니다. 이번 예제에서는 캐릭터가 씬 안에서 움직일 때 발자국 사운드 파일을 재생하려고 합니다. 이 사운드는 Jordan Mechner의 첫 번째 Prince of Persia 게임에서 가져온 것으로, 저의 첫 PC 게임 경험이기도 했습니다. 겉보기에는 간단해 보이는 작업이지만, 실제로는 작은 문제를 하나 포함하고 있습니다.

발자국 사운드를 재생하기 위한 첫 번째 단계는 캐릭터에 Audio Source 오브젝트를 추가하는 것입니다. 이 컴포넌트 안에서 재생할 오디오 파일을 지정하고, 재생과 관련된 다른 속성도 설정합니다.

Audio Source는 씬 안의 오브젝트에 추가해야 하는 컴포넌트입니다. 이 오브젝트는 캐릭터일 수도 있고, 문이나 공일 수도 있으며, 보이지 않는 오브젝트일 수도 있습니다. 예를 들어 캐릭터가 특정 방에 들어가거나 특정 아이템에 가까이 갔을 때 오디오를 재생하는 데 유용합니다.

오디오를 Main Camera에서 들을 수 있으려면 Camera에 활성화된 Audio Listener 컴포넌트가 있어야 합니다. 새 Unity 프로젝트에서는 기본적으로 Main Camera에 활성화된 Audio Listener가 포함되어 있습니다. 사용자가 오디오를 듣기를 원할 것이라고 가정하기 때문입니다. 만약 기본 Audio Listener가 없다면, Main Camera 오브젝트의 Inspector에서 추가할 수 있습니다.

제 경우에는 오디오 파일을 캐릭터에 연결해야 합니다.

프로젝트 안에는 Player 오브젝트가 있으며, 이 오브젝트는 Main Camera의 부모입니다. 이동 스크립트는 Player 오브젝트에 연결되어 있고, 카메라에는 시점을 회전하기 위한 스크립트가 추가되어 있습니다. 따라서 AudioSource 컴포넌트를 Player 오브젝트에 추가하겠습니다.

새로 생성된 컴포넌트의 탭을 열면, 처음에는 None으로 설정되어 있는 AudioClip 필드를 바로 확인할 수 있습니다.

또한 기본적으로 선택되어 있는 Play on Awake 체크박스도 있습니다. 이 옵션은 게임이 시작될 때 오디오를 자동으로 재생합니다. 특정 상황에서는 유용하지만, 이번 예제에서는 필요하지 않으므로 체크를 해제하겠습니다.

오디오 클립을 프로젝트에 가져오는 방법은 매우 간단합니다. File Browser 창에서 오디오 파일을 Project 탭으로 드래그하거나, Assets - Import New Asset 메뉴를 통해 디스크에서 파일을 선택하면 됩니다.

Unity는 mp3와 같은 다양한 오디오 형식을 지원하며, Project 창에서는 해당 파일 옆에 음표 아이콘이 표시됩니다.

보시다시피 제 프로젝트에는 여러 상황에서 재생하기 위한 오디오 파일들이 이미 포함되어 있습니다. 그중에서 우리가 사용할 파일은 PoP---walk입니다.

다음 단계로 Hierarchy에서 Player를 선택합니다.

그 다음 Project 창에서 PoP---walk 에셋을 클릭한 상태로 드래그합니다.

마지막으로 이 요소를 Player에 연결된 AudioSource 컴포넌트의 AudioClip 필드에 드롭합니다.

앞서 말씀드린 것처럼, 사운드는 캐릭터가 움직일 때 재생되어야 합니다.

이를 위해 캐릭터 이동을 처리하는 스크립트를 열고 필요한 코드를 추가하겠습니다.

먼저 AudioSource 변수를 하나 선언하고, Start 함수 안에서 Player의 AudioSource 컴포넌트를 가져와 초기화합니다.

다음과 같이 작성합니다:

private AudioSource playerAudioSource;

그리고 Start 함수 안에 다음을 작성합니다:

playerAudioSource = GetComponent();

또한 재생할 오디오 파일과 연결할 AudioClip 변수도 하나 생성해야 합니다. 이 변수의 이름은 myAudioClip으로 하겠습니다. Inspector에서 보이도록 SerializeField 속성을 사용합니다.

스크립트를 저장한 후에는 Inspector에서 PoP---Walk 에셋을 스크립트의 myAudioClip 필드로 드래그해야 합니다.

playerAudioSource 정의 바로 아래에 다음 코드를 작성합니다:

[SerializeField] private AudioClip myAudioClip;

스크립트를 저장한 후 Unity Editor로 돌아가, 앞서 설명한 대로 PoP---Walk 에셋을 스크립트의 myAudioClip 필드에 드래그합니다.

현재 상태에서는 오디오가 아직 재생되지 않습니다.

스크립트의 Update 함수에는 사용자의 키 입력을 감지하여 캐릭터를 움직이게 하는 코드가 이미 작성되어 있습니다.

사용자가 캐릭터를 움직이면 Input.GetAxis의 Horizontal과 Vertical 값, 즉 편의상 x와 y로 이름을 바꾼 값은 방향에 따라 -1 또는 1이 됩니다.

이 경우 다음과 같이 작성할 수 있습니다:

if ((Mathf.Abs(x) == 1) || (Mathf.Abs(z) == 1))

playerAudioSource.PlayOneShot(myAudioClip);

그리고 게임을 실행해 볼 수 있습니다. 그러나 이렇게 하면 큰 문제가 발생합니다. Unity는 게임의 모든 프레임마다 오디오 파일을 재생하게 됩니다.

PlayOneShot 함수를 Coroutine 안으로 옮기고 yield return new WaitForSeconds(1)과 같은 1초 지연을 추가해도 상황은 개선되지 않습니다. Update는 매 프레임마다 Coroutine을 호출하기 때문에 결국 같은 오류가 반복됩니다.

따라서 Coroutine은 필요하지 않습니다. 대신 AudioSource가 이미 재생 중인지 확인하는 간단한 조건을 추가해야 합니다. 오디오가 재생 중이 아닐 때만 재생하도록 해야 합니다.

Update 함수 안에서 x와 y 값을 확인하는 if 블록 내부에 다음과 같이 작성합니다:

if (!(playerAudioSource.isPlaying))

playerAudioSource.PlayOneShot(myAudioClip);

이제 스크립트를 저장하고 게임을 실행한 뒤 결과를 확인해 보세요. 아니, 직접 들어보세요.

튜토리얼을 마치기 전에 한 가지 더 말씀드리고 싶습니다. AudioSource 컴포넌트의 AudioClip 필드는 스크립트를 통해 언제든지 변경할 수 있습니다.

즉, 기본 발자국 사운드를 재생하다가 캐릭터가 자갈 위나 해변 위를 걷는 경우, 또는 다른 표면 위를 걷는 경우에 따라 오디오 클립을 교체할 수 있습니다. 이러한 표면은 Collider를 통해 식별할 수 있습니다.

또한 캐릭터가 날 수 있는 경우라면, AudioSource를 비활성화하여 사운드가 재생되지 않도록 할 수도 있습니다.

이것으로 이번 튜토리얼을 마치겠습니다. 도움이 되었기를 바랍니다. 곧 다시 만나요!

이 사이트는 제 작업 일부를 소개하기 위한 목적만을 가지고 있으며, 어떠한 홍보 목적도 포함하지 않습니다. 현재 맞춤 작업, 컨설팅 또는 기타 어떤 형태의 업무 협업에 대한 요청도 받고 있지 않으며, 이에 대해 응답하지 않으니 양해 부탁드립니다.


확장된 개인정보 및 쿠키 사용 정책