이 개발자 블로그는 언리얼 엔진 사용 시 사운드 디자인 프로세스 또는 구현 측면에 관심이 있는 모든 분을 대상으로 합니다. 에픽게임즈는 에픽게임즈 런처에서 설치 가능한 자체 '슈팅 게임' 프로젝트의 오디오를 전면 수정하기 위해 저를 채용했습니다. 이 프로젝트는 에픽에서 다운로드 횟수가 매우 높은 입문자용 템플릿이므로 아직 사용해 보지 않았다면 한번 사용해보세요.
저는 오디오 애셋을 전부 재구성했을 뿐만 아니라 확장 가능한 블루프린트 로직을 포함하고 사물을 명확하고 이해 가능한 방식으로 표현하기 위해 최선의 노력을 다했습니다. 또한, 대부분의 사운드 디자이너가 해보고 싶어하는 몇 가지 유용한 파라미터, 시스템, 변수, 컴포넌트도 포함했습니다. 제가 설정한 것은 단지 디자인 제안 사항, 그리고 언리얼 엔진에서 오디오를 구현하는 수많은 방식 중 하나에 불과합니다. 개인적으로 느낀 건데 게임 오디오 커뮤니티에 한 가지 오해가 있는 것 같습니다. 사람들은 '차세대 사운드'(이게 무슨 의미이든)를 실현하려면 UE 프로젝트에 꼭 미들웨어를 넣어야 한다고 생각하는데 이는 전혀 사실이 아닙니다.
기술적 능력을 갖춘 콘텐츠 제작자가 되는 것이 얼마나 중요한지 더 많은 게임 오디오 제작자가 알게 되기를 바라고 있습니다. 언리얼 엔진 네이티브 툴과 기능이 대폭 향상되었다는 점은 의심의 여지가 없습니다. 이건 모두 에픽의 프로그래밍 팀과 QA 팀이 지난 몇 년간 열심히 구현하고 테스트하고 수정한 덕분입니다. 그들은 앞으로도 매우 당차고 흥미로운 로드맵을 선보일 것입니다. 저희와 같은 전문 사운드 디자이너에게는 이러한 툴과 기술의 이점을 활용해서 더 나은 게임 기획자로 변신할 책임이 있다고 생각합니다. 단순하게 느껴지는 경우가 많은 구현 작업을 완료하려고 굳이 프로그래머에게 의존할 필요가 없는 것이죠. 특히, 앞으로가 블루프린트의 시대란 걸 감안한다면 더더욱 말이죠.
저는 2012년부터 언리얼 엔진을 적극적으로 옹호하며 사운드 디자인 및 구현 기법에 대한 열정을 불태워 왔기 때문에 이 프로젝트의 일원이 된 것을 영광으로 생각합니다. 모든 걸 고려했을 때(사운드 디자인, 구현, 탐색, 버그 수정, 플레이테스트, 회의, 동기화 등) 저는 이 작업에 15~20일 정도가 소요될 것으로 예상했습니다. 프로젝트에 동기화한 후에는 오디오 서브레벨의 모든 액터를 선택하고 삭제하는 것이 정말 보람차게 느껴졌습니다. 그러면 여기서 제 경험담을 간단히 말씀드리고, 제가 머리에 새겨 두었던 몇 가지 핵심 사항을 소개해 드리겠습니다.
프로젝트 목표
이 프로젝트에서 저의 주요 목표는 사운드 환경을 좀 더 현대적이고 역동적인 느낌으로 업데이트하는 것이었습니다. 이전 애셋은 과도하게 압축되었고 믹스는 최적으로 처리되지 않았으며 애셋 사운드는 꽤나 구식이었습니다. 또한 주파수와 볼륨 측면에서 듣기에 다소 부담되는 뮤직 트랙도 있었습니다. 이것들은 결과적으로 개별 게임 이벤트를 실험할 수많은 기회를 날렸고, 게임 플레이를 제대로 살리지 못했습니다. 더 큰 문제는 무기 타격감이 부족했고, 환경에서 앰비언스는 공간감과 질감이 부족했고, 발소리는 너무 크고 육중했으며, 픽업 사운드는 거의 폭발음처럼 들렸습니다. 모든 애셋의 개선점을 나열할 수 있지만 시간 관계상 요약하자면 모든 애셋이 업데이트가 필요하다고 생각했습니다. 그래서 기본적으로 게임에 존재했던 모든 걸 없애고 처음부터 다시 만들었습니다.오디오 서브레벨의 모든 요소를 제거하는 영상
사운드 재구성
슈팅 게임의 오디오는 뭔가 촌스러웠고 믹스 밸런스가 맞지 않았습니다. 아무래도 이 프로젝트는 언리얼 엔진의 구매자와 신규 사용자가 가장 많이 다운로드하는 샘플 중 하나다 보니, 사람들이 네이티브 오디오 엔진 수준이 어떤지 오해를 할 만도 했습니다. 그 외에도 노후된 사운드와 오락가락하는 구현 전략이 샘플 게임의 재미를 떨어뜨리고 있었습니다. 오디오 애셋 및 구현 측면에선 주요 사운드 클래스 간에 밸런스도 맞지 않았습니다(예: 무기/발소리/픽업). .wav 애셋은 동적 범위가 제한적이었고 같은 주파수 공간에서 서로 부딪히고 있었습니다. 또한 개성과 표현력도 부족했습니다. 사운드 환경은 그냥 밋밋하게 느껴졌고, 그 결과로 경험으로 이어지는 감정적 연결점이 전부 줄었습니다. 이건 어떤 미디어에서든 오디오가 살려야 할 가장 중요한 역할인데 말이죠. 사운드 디자이너는 비디오 게임의 모든 원인이나 결과에 매우 중요한 게임 기획과 스토리를 지원하는 목적을 품은 의미 있는 오디오가 기획되어 있는지 확인하고 싶어합니다. 이러한 문제 때문에 저는 전면적인 재구성이 필요하다고 느꼈습니다.그 후로 며칠 동안 저는 마이크와 필드 레코더를 들고 샌디에이고의 여러 지역을 돌아다니며 음원 소스를 대량으로 녹음했습니다. 저는 환경음에서 여러 표면의 발소리에 이르는 다양한 사운드를 모았습니다. 또한 제 스튜디오에서 금속 충격음이나 질감이 느껴지는 여러 가지 소리를 직접 녹음했습니다. 그리고 다양한 신디사이저로 훌륭한 음원을 확보했으며 신비롭고 미래적인 느낌의 공상 과학 세상을 연상시키는 FX 체인음을 통해 여러 가지의 특이한 소리를 다 시험했습니다. 저는 프로젝트에 이미 존재하는 기존 시스템의 구현과 학습으로 대부분의 시간을 보내게 될 것을 알았습니다. 일부 시스템은 아직도 사용되고 있죠. 또한 구현 프로세스에 어떻게 접근하면 좋을지, 그리고 어떤 새로운 시스템이 필요할지에 대한 아이디어를 구상하는 데 많은 시간을 할애했습니다. 이 프로젝트가 재미있었던 이유 중 한 가지는 에픽의 시니어 오디오 프로그래머인 애론 맥러렌(Aaron McLeran)과 테크니컬 사운드 디자이너인 댄 레이놀즈(Dan Reynolds)가 사실상 제가 원하는 대로 작업할 수 있도록 해주었기 때문입니다! 그러면 좀 더 자세히 살펴보겠습니다.
구현
이 프로젝트의 일부 게임 플레이 시스템은 프로젝트 수준의 C++ 코드로 하드코딩되었습니다. 다른 경우엔 기존 구현을 그대로 유지하면서, 단순히 사운드 큐와 소스 파일만 새로운 사운드 콘텐츠로 교체했습니다. 예를 들어 무기 발사 시스템은 하드코딩된 루프 사운드 시스템을 사용합니다. 이 시스템은 슈팅 게임에만 있는 커스텀 사운드 큐 노드를 참조합니다. 사운드 노드 로컬 플레이어라 불리는 이 노드는 1인칭 및 3인칭 인스턴스화에 따라 애셋을 전환합니다. 애런과 댄은 보통 이 과정이 사운드 큐가 아닌 더 높은 레벨의 게임 플레이 코드 시스템에서 이루어진다고 알려주었습니다. 하지만 슈팅 게임의 경우에는 엔지니어링이 우선 순위이므로 슈팅 게임에서 로컬 대 비로컬 플레이어 사운드의 구현 방식을 변경할 수는 없었습니다. 저는 새로운 기능이나 코드 작업에 프로그래머의 도움을 받지 않으면서 사운드를 재구성해야만 했습니다. 따라서 저는 계속 이 구현 방식을 사용해야 했습니다. 임팩트 템플릿, 스팅어, 픽업과 같은 다른 구현 사례의 경우 저는 보통 사운드 후크만 남기고 사운드 자체와 관련 큐만 교체했습니다.나머지 구현 작업과 관련해선 대부분의 사람들이 유용하다고 느낄 가능성이 높은 세 가지 주요 영역에 집중해야겠다는 생각을 했습니다. 그 영역은 다음과 같습니다.
- 오버랩 이벤트: 오버랩 이벤트에 따라 앰비언스와 단발 사운드를 변경했습니다.
- 액터 블루프린트: 용도 변경 및 커스터마이징을 위한 커스텀 유틸리티를 만들었습니다.
- 머티리얼 기준의 발소리: 서피스 타입 접촉 결과에 따라 발소리나 기타 소리를 변경했습니다.
오버랩 이벤트: 개인적으로는 오버랩 이벤트가 언리얼 엔진 구현의 가장 기초라고 생각합니다. 오버랩 이벤트를 사용하면 레벨에 배치할 만한 수준에서 블루프린트 이벤트를 만들 수 있습니다. 블루프린트 속에서 사운드 디자이너들은 자신들이 디자인할 수 있는 모든 사운드 시스템의 많은 부분을 제어할 수 있습니다.
그림 1. 브러시 액터를 배치하여 레벨에 커스텀 오디오 동작을 구현할 영역에서 오버랩 이벤트를 트리거합니다.
이를 보여주기 위해 위의 그림 1에는 방의 레이아웃과 일치하는 커스텀 볼륨(에코용)과 트리거(앰비언스용)를 배치했습니다. 플레이어가 레벨에서 이러한 보이지 않는 브러시 볼륨을 중첩시킬 때마다 우리는 다음과 같은 작업들을 수행할 수 있습니다.
- 공간에서 재생되는 방의 톤이나 앰비언트 베드를 변경합니다.
- 우리가 공간에 있는 동안 플레이어의 월드 포지션 주변에서 랜덤으로 더욱 독특한 단발 사운드가 트리거되도록 전환합니다.
- 공간 내 모든 사운드의 에코를 변경합니다.
- 볼륨 안팎으로 사운드를 켜고 끕니다.
- 이 볼륨이나 다른 볼륨으로 재생 중인 HPF 및 LPF를 사용합니다.
그림 2. 오버랩 이벤트는 앰비언스를 제어하는 로직을 실행합니다.
그림 2는 오버랩 이벤트가 발생하면 실행되는 간단한 블루프린트 스크립트를 보여줍니다. 우선 저는 오버랩 이벤트의 원인이 된 액터와 제어 중인 폰이 동일한지 확인합니다. 그런 다음 월드에 있는 오디오 컴포넌트를 레퍼런스로 가져와 안으로 서서히 사라지게 페이드인시킵니다. 아주 간단하죠. 올바른 액터가 볼륨을 트리거하는지 확인해야 하는 이유는 NPC(또는 네트워크에 연결된 다른 플레이어가 조종하는 캐릭터)의 행동에 따라 로컬 클라이언트의 앰비언트 사운드가 변경될 수도 있기 때문입니다. 이런 상황이 되면 급속도로 혼란이 일어나겠죠.
그림 3. 이 오디오 로직은 플레이어의 월드 위치 주변의 랜덤 벡터 좌표에 단발 사운드를 생성합니다.
그림 3에서는 오버랩 이벤트, 그리고 플레이어의 위치 주변에 랜덤 단발 사운드를 주기적으로 생성하는 Timer By 함수를 만들었습니다. 이러한 사운드가 생성되는 거리와 빈도는 PIE에서 여러 가지 사운드를 실험하며 쉽게 변경하거나 반복 가능한 공개 float 변수를 통해 완전히 사용자 정의합니다. 이뿐만 아니라 큐 내에 있는 기본 피치 및 볼륨 변형도 당연히 조정됩니다.
그림 4. 'BP_Audio_Spline' 블루프린트의 오디오 로직.
액터 블루프린트
아직 블루프린트의 위력을 잘 모르겠다면 제가 설명해 드리겠습니다. 블루프린트는 극도로 강력하며 수많은 오디오 기능과 커스터마이징 옵션을 제공해 줍니다. 예를 들어 그림 4는 청자와 가장 가까운 스플라인 포인트에서 사운드를 재생하는 로직을 처리하는 유틸리티 스크립트를 보여줍니다. 아래의 그림 5는 사운드가 이동하는 스플라인 경로의 예를 보여줍니다.그림 5. 저는 높이 솟은 레벨에서 발코니 가장자리를 따라 스플라인을 그렸습니다. 루핑되는 바람 소리는 플레이어 포지션에 가장 가까운 스플라인 포인트에서 발산됩니다.
가장 일반적인 사용 사례로는 배관에 흐르는 물이나 굽이치는 강이나 하천의 반복되는 물소리 등이 있습니다. 이는 음원이 더 크고 분산된 지점에서 나오는 느낌을 주거나, 한 곳의 음원 또는 일련의 음원들의 느낌을 줄 때 사용됩니다.
그림 6. 스플라인에 가장 가까운 플레이어 위치를 따라가는 오디오를 시각적으로 표현했습니다.
이 프로젝트에서는 몇몇 영역에 사용 중입니다. 그림 6은 발코니 가장자리를 따라 사용한 사례를 보여줍니다. 저는 단순히 오디오가 따라갈 수 있는 스플라인 경로를 생성하고, 이 경로에서 재생할 바람/외부 루핑 사운드를 사용했을 뿐입니다. 결과적으로는 가장자리에 더 가까이 갈수록 바람 소리가 더 크게 들리는 느낌이 듭니다. 하지만 실제로 볼륨이 늘거나 줄지는 않습니다(즉, 일련의 단발 사운드가 생성될 뿐임).
머티리얼 기준의 발소리
그림 7. 라인 트레이스의 접촉 결과에 따라 발소리를 변경하는 블루프린트 스크립트입니다.
일반적으로 캐릭터가 걷거나 상호작용하는 피지컬 머티리얼에 따라 발소리나 여러 가지 소리가 바뀌게 만들기 위해 언리얼 엔진의 코드를 바꿀 필요가 없습니다. 그림 7은 발소리와 점프 후 착지의 로직을 보여줍니다(즉, 캐릭터가 점프 후 땅을 밟을 때 재생되는 소리). 이러한 스크립트는 라인 트레이스를 사용하고 접촉된 대상에 대한 정보를 얻고 그 결과에 따라 사운드를 변경하고 싶은 모든 경우에 사용 가능합니다.
그림 8. Playsound 노티파이는 사운드를 트리거하는 반면 애니메이션 노티파이는 애니메이션 블루프린트(Anim BP) 그래프 이벤트를 트리거합니다.
그림 8은 이 애니메이션 블루프린트에 보이는 이벤트가 다양한 달리기/질주 애니메이션에서 'Footstep'으로 이름을 정한 개별 애니메이션 노티파이 이벤트에 의해 트리거됨을 보여줍니다.
이 방법을 활용하기 전에 먼저 프로젝트의 여러 표면에 모든 피지컬 머티리얼이 실제로 구성되어 있는지부터 확인해야 합니다. 어떤 피지컬 머티리얼 타입이 존재하는지는 프로젝트 세팅에서 정의합니다. 저는 이 샘플 프로젝트에서 타일, 그래스, 메탈 머티리얼만 사용합니다. 하지만 프로젝트에 영화 '터미네이터'의 '액체 금속'과 같은 독특한 머티리얼이 있다면 프로젝트 세팅에서 그걸 정의해야 합니다. 구성한 후에는 이러한 서피스 타입을 레벨에 배치된 피지컬 머티리얼과 메시에 할당할 수 있습니다. 이는 배경 아티스트가 그래픽 때문에 미리 구성한 경우가 대부분이므로 사운드 디자이너는 구성되어 있는 것을 확인 후 그대로 사용하기만 하면 될 때가 많습니다.
그림 9. 'map' 변수를 사용하여 피지컬 머티리얼 타입 및 사운드 큐를 연결
그림 9에서는 변수 타입 맵을 생성해 두었습니다. 여기에 라인 트레이스의 접촉 결과를 연결하여, 접촉한 서피스에 따라 각기 다른 사운드를 재생합니다. 블루프린트 스크립트는 다음과 같은 논리적 시퀀스를 수행합니다.
- 애니메이션 노티파이가 이벤트를 트리거합니다.
- 폰 오너 및 캐스트를 플레이어 폰 BP로 가져옵니다.
- 그런 다음 월드 위치를 가져옵니다(시각 벡터 위치로).
- 그런 다음 100유닛을 차감합니다(엔딩 벡터 위치로 사용).
- 해당 좌표를 사용하여 라인 트레이스를 수행합니다.
- 라인 트레이스로 서피스에 접촉하면 그게 무엇이었는지 알려줍니다.
- 접촉된 피지컬 머티리얼을 반환하고 내가 맵 변수를 사용하여 설정한 사운드 레퍼런스를 찾습니다.
- 그런 다음 내 맵 변수에서 감지된 대상의 결과를 사용하여 'Sound To Play'라 불리는 사운드 변수를 설정합니다.
- 마지막으로 플레이어 폰의 메시를 참조하고 메시에 연결된 발소리를 생성합니다.
마무리
일반적으로 언리얼 엔진에서 아이디어나 시스템을 구현하는 방법은 많습니다. 보통은 작업 자체를 수행하는 방식에 있어 옳고 그름이 없지만 더 나은 방식이 있을 수 있습니다. 팀에서 일하고 있다면 프로그래머나 디자이너에게 요청하여 블루프린트 로직을 주기적으로 검토하고 비평하는 것이 좋습니다. 오디오 외의 시스템을 공부하고 활용하면 할수록 디자인 프로세스에 더욱 깊게 몰입할 수 있습니다. 그러면 언리얼 엔진을 사용하는 한 사람의 개발자로, 다른 게임 기획자나 개발자와 동등한 선상에 설 수 있습니다. 꽤 멋지지 않나요?언리얼 엔진 오디오에 대해 자세히 알아보려면 제 페이스북 그룹인 '언리얼 엔진 오디오 팁 & 트릭'에 가입하여 Udemy에 대한 UE 강좌를 확인해 보세요. 언리얼 엔진 포럼에 참여하면 매튜 발트슈타인(Mathew Wadstein)의 WTF Is 시리즈와 같은 유튜브(YouTube) 채널을 살펴볼 수 있습니다. 또한 에픽은 최근에 유익한 온라인 학습 강좌를 개설했습니다. 언제든지 제 링크드인(Linkedin)이나 웹사이트 Craftmediagroup.com을 통해 자유롭게 문의해 주시기 바랍니다.
감사합니다!