소개
이 블로그 글은 Wildlife Studios의 'Suspects: Mystery Mansion' 게임의 음성 채팅 시스템에 관한 것입니다. 안녕하세요. 저희는 Leo Perantoni(테크니컬 사운드 디자이너)와 Felippe Lopes(오디오 프로그래머)입니다.
기존 음성 시스템의 API를 GME로 교체하는 작업을 진행했습니다. 그렇게 하면 오디오 품질을 개선하고 Wwise 내부 신호 흐름과 공간화 구조(spatialization structures), 그리고 효과 체인(effect chains)을 사용하여 음성 채널에서 전송되는 시그널을 제어할 수 있기 때문입니다.
Suspects는 기본 음성 채팅, 다양한 게임 모드 및 정기적인 콘텐츠 업데이트가 있는 소셜 추론 게임입니다.
저희 게임의 음성 채팅은 기능에 영향을 미치는 상황별 규칙이 많기 때문에 제대로 설정하는 것이 어려웠습니다. 예를 들어, 2D 및 3D 채팅을 혼합하여 플레이어의 상태에 따라 다른 채널을 듣고 있는 플레이어와 채팅하는 경우가 있습니다. 이 때, 죽은 플레이어는 감쇠가 있는 3D로 살아있는 플레이어의 소리를 듣고 감쇠 없이 2D로 다른 죽은 플레이어의 소리를 듣습니다. 그리고 살아있는 플레이어는 다른 살아있는 플레이어의 말만 들을 수 있어야 하죠. 자칫 잘못하면 매우 헷갈리게 돼버리겠죠.
Wwise용 Tencent GME 플러그인을 사용하여 음성 채팅을 구현한 방법을 살펴보겠습니다.
GME를 사용하는 다양한 방법
Suspects에는 음성 채팅 상태를 제어하는 많은 시스템이 있습니다.
- 자신과 다른 사람의 음소거 및 음소거 해제와 같은 플레이어 동작
- 긴급 회의(emergency meeting) 시작 및 종료와 같은 게임 플레이 동작
- 신뢰 및 안전(trust and safety)과 같은 시스템 동작
이러한 모든 음성 채팅 상태 변경 시스템은 동시에 일어날 수 있습니다. 예를 들어, 플레이어는 마이크를 음소거하고, 무음 시스템(silence system)은 다른 플레이어의 말이 들리지 않도록 하는 동시에, 신뢰 및 안전 시스템은 아무도 말할 수 없게 만드는 경우가 그렇습니다.
따라서 이러한 계층화된 시스템 접근 방식을 해결하기 위해 의도 설계(intention design)를 사용했습니다. 각 시스템은 원하는 음성 채팅 상태의 의도를 선언합니다. 그런 다음 이러한 원하는 상태가 병합되고 단일 채널/Room을 사용하여 음성 채팅 컨트롤에 적용됩니다.
로비/긴급 회의
로비나 긴급 회의 중에 플레이어는 2D 공간에서 서로 대화할 수 있습니다. 이를 위해 일반 수신 및 전송 이벤트를 호출합니다. 이 게임 상태에서 플레이어는 다른 특정 플레이어(State 시스템 사용) 또는 자신을 음소거 및 음소거 해제할 수 있습니다.
AddAudioBlockList 및 RemoveAudioBlockList GME 이벤트를 사용하여 이러한 플레이어 작업을 처리하고 음소거된 플레이어 목록을 로컬에 저장하여 다른 모든 음성 채팅 유형에 동일한 작업을 적용할 수 있습니다.
유령 채팅 게임 모드(Ghost Chat Game Mode)
플레이어가 임포스터에 의해 퇴장되거나 사망하면 플레이어는 다른 모든 죽은 플레이어와 유령 모드 채팅에 들어갑니다. 유령은 다른 유령(또는 게임 모드에 따라 다른 살아있는 플레이어)을 들을 수 있지만 긴급 회의가 호출되면 회의에서 살아있는 플레이어의 토론만 들을 수 있습니다.
이를 위해 죽은 플레이어가 2D로 서로 대화할 수 있도록 경기 중에만 음소거를 해제하고 긴급 회의가 시작되면 다시 음소거합니다.
잡담 게임 모드(Chit Chat Game Mode)
잡담 게임 모드에서 플레이어는 근처에 있는 다른 플레이어와 대화할 수 있습니다. 이 기능을 구현하기 위해 다음을 수행했습니다:
1. SetRangeAudioRecvRange GME 이벤트 메소드를 근접 반경 값으로 호출합니다.
2. Wwise에서 감쇠를 사용하여 3D 수신기 이벤트(receiver event)를 만들었습니다.
3. 로비에 있는 다른 모든 살아있는 플레이어를 위해 이 이벤트를 호출했습니다.
4. SetReceiveOpenIDWithGameObjectID SetUserID 메소드에서 사용한 것과 동일한 userID를 가진 GME 이벤트를 호출했습니다.
이 단계를 거친 후 우리는 잡담(Chit Chat) 매치를 시작할 준비가 되었습니다. 플레이어가 이동할 때마다 SetSelfPosition 메소드를 사용하여 GME의 로컬 위치를 업데이트합니다.
잡담 모드의 긴급 회의
잡담 게임 모드 긴급 회의와 표준 게임 모드 긴급 회의의 차이점은 플레이어의 음소거를 해제하기 전에 3D 수신기 이벤트(Chit Chat 모드)와 2D 수신기 이벤트(Standard 모드) 사이를 전환해야 한다는 것입니다. 회의가 끝나면 동일한 일이 발생하며 빈 값으로 SetReceiveOpenIDWithGameObjectID GME 이벤트를 호출합니다.
잡담 모드의 유령 채팅
이 구현은 가장 어려운 일이었습니다. 유령은 2D 공간에서 다른 유령과 이야기하고 들을 수 있으며 동시에 감쇠된 3D 공간에서 살아있는 플레이어의 말을 들을 수 있습니다.
잡담 모드에서 유령 채팅을 구현하기 위해 다음을 수행했습니다:
1. 2D 수신기 이벤트를 호출합니다.
2. 죽은 플레이어에 대해서만 3D 수신기 이벤트를 중지합니다.
3. SetReceiveOpenIDWithGameObjectID 죽은 플레이어에 대해서만 값이 비어 있는 GME 이벤트를 호출합니다.
음소거된 목록은 로컬에서 처리되기 때문에 살아 있는 플레이어는 유령 채팅에서 무슨 이야기를 하는지 들을 수 없습니다.
아래 이미지는 Suspects 음성 채팅의 일반적인 예시를 보여줍니다. 모든 상호 작용은 단일 채널에서 실행되고 클라이언트 측에서 제어됩니다.
- 플레이어 A와 B는 살아 있고 둘이서만 대화가 가능합니다.
- 플레이어 C와 D는 죽었고 서로 대화할 수 있지만, 플레이어 A와 B의 말은 듣기만 가능합니다.
- 플레이어 E와 F는 살아 있고 플레이어 A와 B의 감쇠 범위 밖에 있으며 둘이서만 대화할 수 있습니다.
Wwise 통합
GME 오디오 효과를 위한 Wwise 설정은 매우 간단했습니다. 플러그인을 Wwise 세션으로 가져온 후 생성된 Work Unit은 거의 바로 사용할 준비가 되어있습니다. 상황별 음성 채팅에 대한 요구 사항이 다르기 때문에 약간의 커스터마이징만 거치면 되었습니다.
기본 구조는 위에서 아래로 다음과 같이 작동합니다:
- 효과 체인의 끝에서 인스턴스화된 Tencent GME Send 효과가 있는 오디오 오브젝트
- Tencent GME Receive 효과가 있는 오디오 오브젝트 (Send 효과에서 수신하는 '리스너')
- Tencent GME Session 효과가 있는 Main System 오디오 장치 (Room 및 사용자 ID 생성)
기본 설정만으로 얻을 수 있는 음성 품질은 이미 꽤 훌륭하지만, 동시에 서로의 말을 들을 수 있는 최대 10명의 플레이어가 있는 Room을 다루기 때문에 어떤 식으로든 다이나믹을 제어해야 했습니다. 음성 채팅을 다룰 때 주요 문제 중 하나는 예측할 수 없는 행동입니다. 플레이어는 조용한 방에 있을 수도 있고, 반대로 잡음이 많은 환경에 있어 매우 시끄러울 수도 있습니다. 저희는 이러한 예측할 수 없는 상황을 관리하는 데 도움이 되는 몇 가지 Wwise 플러그인을 사용하기로 결정했습니다.
저희 방향과 테스트 결과를 참고하여 Wwise Parametric EQ를 사용하여 지속적으로 발생하는 특정 거친 주파수를 처리하고 고역대을 증폭하여 먹먹한 마이크를 더욱 깨끗이 들리도록 처리했습니다. 또한 여러 플레이어가 서로 소리치는 상황을 처리하기 위해 이 시스템의 신호 경로의 여러 단계에서 Wwise Peak Limiter를 사용했습니다. 마지막으로 GME Send 이전에 Wwise Meter를 사용하여 목소리의 볼륨에 따라 캐릭터 스프라이트 주변의 빛나는 시각 효과를 제어하여 플레이어가 누구의 목소리를 듣고 있는지 쉽게 알아볼 수 있게 했습니다.
Unity에서 GetRTPCValue 메소드로 Wwise Meter 값을 읽고 값을 서버로 전송하면 서버에서 다른 플레이어의 클라이언트에 복제되어 빛나는 하이라이트를 제공합니다.
GME Send 이후에 GME Receive 효과가 있는 두 개의 오디오 오브젝트가 있습니다. 하나는 감쇠 또는 스피커 패닝이 없는 2D 채팅용이고 다른 하나는 감쇠 및 위치 지정이 있는 3D 채팅용이며 이는 공통 이미터처럼 처리됩니다. 마지막 단계는 메인 시스템 출력 오브젝트의 GME Session 효과입니다.
저희가 미래에 고려하고 있는 한 가지는 GME 시스템에 의해 가능하게 되었으며 음성 채팅 신호 경로에서 보다 창의적인 오디오 처리를 사용하는 것입니다. 예를 들어 Ghost Chat(죽은 플레이어 채널)에 있는 경우 GME Send에 약간의 딜레이 및 리버브를 추가합니다. GME를 사용하면 이와 같은 작업을 매우 쉽게 구현할 수 있습니다.
음성 채팅을 창의적으로 사용한 또 다른 예시는, 팀원과의 거리에 따라 깨끗한 음성과 라디오 음성을 혼합하는 경우입니다. 거리 RTPC로 효과의 dry/wet 매개 변수를 제어하여 GME로 이를 쉽게 구현할 수 있습니다. 깨끗한 음성과 라디오 음성 사이를 변경하기 위한 RTPC 스레숄드에서 라디오 클릭 사운드를 트리거하여 몰입감을 높일 수 있습니다.
그리고 이것은 Wwise 구현 측면을 다룹니다.
결론
GME는 음성 채팅을 빠르게 반복하는 데 매우 유용하며, Wwise에서 이를 수행할 수 있는 모든 도구가 있으면 실시간으로 음성 품질을 제어하는 데 매우 유용합니다.
모든 지원 및 음성 채팅 플레이 테스트 세션에 대한 Wildlife 오디오 팀, 엔지니어링 및 QA 지원을 위한 Suspect 팀, 그리고 사랑하는 Suspect 커뮤니티에 감사드립니다. 저희의 새로운 음성 채팅을 재밌게 즐기셨으면 좋겠습니다.
Wwise GME를 사용해 보세요
|
레오 페란토니 (LEO PERANTONI) |
댓글