UE5でインゲームカットシーンにおけるサウンド減衰を考察する

# はじめに

ゲーム中におけるプレイヤーの操作シーンとカットシーンをシームレスに切り替える状況を想定した際、視点とサウンドの聴取位置のギャップによる違和感が生じることがあります。
この記事では、そんなシチュエーションにおける解決策を、簡単な実装法を絡めて紹介します。

UE5.4 + 基本的にブループリントを使用しています。他バージョンでも基本的に同様の実装が可能です。

# リアリティと演出のギャップ

<iframe width="560" height="315" src="https://www.youtube.com/embed/QoLKnhYejwA?si=1PyJDo3TvwvfxRvT" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

3D空間上に配置されたサウンドは、距離による減衰でカメラの距離に応じたボリュームで再生されています。
前半はカメラが近く、いい感じに効果音が聞こえるのに対し、後半ではカメラが遠ざかり、爆発音などはほぼ聞こえません。サウンドはTPS視点でデザインされているため、そのまま俯瞰視点に移行した場合過度な減衰がかかってしまっていますね。
現実世界ならこれは正しい挙動なのですが、ゲームや映像という媒体ならばリアリティよりも臨場感を重視したいものです。
この解決には、主に2つの方法があります。

- シーケンサー上にサウンド再生用のトラックを作り、減衰のないサウンドを再生する
- サウンドの聴取位置をカメラと分離して設定する

前者がサウンドの減衰や定位を全く無視してしまうのに対し、後者では減衰や定位を活かしつつ、サウンドとの丁度良い距離感を探ることができるお得な実装法となっています。

## Audio Listenerを手動で設定する

次の画像は通常の（現実世界と同様の）イメージです。
![Listener_01_A.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/c7a75596-04f6-f2fb-754d-ae020320751b.png)

これに対し、Audio Listenerを手動で設定すると、現実世界とは違い、目と耳が分離できることになります。
![Listener_01_B.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/03c7077f-8232-ec3c-6a06-913f4d918fc5.png)

Audio Listenerを設定するには、**Set Audio Listener Override**ノードを使用します。
![Listener2_A.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/50885f20-d87f-4b26-8cab-ef2617beb308.png)
![Listener2_B.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/ca2a593a-f404-2158-b808-bcc620d69532.png)
「Attach to Component」ピンへコンポーネントを指定すると、以後そのコンポーネントにリスナーが追従することになります。
「Location」「Rotation」ピンでは、都度リスナーの位置や方向を指定できます。

上書きしたリスナー座標を元に戻したい場合は、**Clear Audio Listener Override**ノードが使用できます。
![Listener_C.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/eac56627-3801-562b-5dc8-e6bbf165a2e9.png)



これにより、サウンドの聴取位置をプレイヤーと近い位置に手動で設定した例がこちらです。

<iframe width="560" height="315" src="https://www.youtube.com/embed/WQj3-YHhqCo?si=vdTM1euOsJwZMtEc" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

カメラが俯瞰視点になって離れても、リスナーの位置は変わらず臨場感のあるサウンドを聞くことができます。


## リスナーをどの位置に置くのが適切か？
この例ではTargetPointアクターをキャラクターの近くに配置し、その座標をリスナーの座標としています。
これにより、聴取位置はカメラの位置にかかわらず一定となっています。
![CameraChange_ListenerLoc_A.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/48e8d882-d52a-7d81-6944-266954ae03a2.png)
![CameraChange_ListenerLoc_B.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/af66dab1-5a16-7c2e-d4a4-61a19adcf801.png)

では、通常のゲームシーンでもリスナーの位置を変更するとどうなるでしょうか？
カメラとプレイヤーキャラクターの位置を取得し、その間の座標にリスナーを置くことで、「キャラクターの聞いている音」をプレイヤーにも届ける事が可能になります。
次の画像では、緑色の円では神視点（プレイヤー）寄り、赤い円ではキャラクター体験寄りとなります。
![CameraChange_ListenerLoc_C.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/a049fcbc-75fd-b68e-2ce7-0995cd78edeb.png)

どちらが体験として適しているかはゲームやプレイヤーによるところが大きいです。
ゲームによってはこの2点間のどちらにリスナーを置くかをコンフィグで設定できるものもあります。


俯瞰視点で進行するゲームにおいては、

- リスナー座標（Location）はプレイヤーに寄せる
- リスナー方向（Rotation）はカメラ方向で固定

といったように、LocationとRotationを別々に設定することで臨場感を残しつつ、効果音の定位により「どこで何が起こっているか」を情報として届けることが可能になります。
![CameraChange_ListenerLoc_D.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/8d2f3d57-96d5-af27-a66e-596323aeb2ba.png)

また、サウンド減衰を強めにしてもプレイヤーの発するサウンドだけは大きめに（減衰を弱めに）しても良いかもしれません。
プレイヤーキャラクターの発する音は操作のフィードバックとして重要な情報なので、優先的にサウンドが聞こえるようにすることで、操作感がアップします。

ゲームの視点や演出の意図に合わせたリスナー設定を行い、効果的な体験を作ってみましょう。


# カットシーンでプレイヤーとカメラが分離する場合
次は、こちらの例を見てみましょう。
<iframe width="560" height="315" src="https://www.youtube.com/embed/DcZdGlvxD7o?si=jHAkxnJklu9kxw5h" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
カメラがプレイヤーキャラクターから離れて通路を進んでいくと、敵らしきキャラが奥へと進んでいく様が見えます。
しかし、サウンドがパッとしません。
リスナーはプレイヤー寄りになっていますが、カットシーンのカメラがプレイヤーから離れる場合、遠いところでのシーンでは聞かせたいサウンドが全く聞こえなくなってしまっているためです。

これを改善するため、カットシーン開始に合わせてリスナーの位置を変更してみましょう。
<iframe width="560" height="315" src="https://www.youtube.com/embed/srsglzeGLgU?si=k7Hydm6LhqK683K-" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
吹雪の音が遠ざかり、敵キャラの発する音が明確に聞こえるようになりました。

こういった演出をデザインしたい場合、カットシーン開始時、終了時にリスナーをプレイヤーから分離する処理を入れることが重要になります。

簡単な方法としては、**Lerp**ノードを使用しプレイヤー座標からカットシーンのカメラ座標に徐々に近づける、というものがあります。
![CameraMove_A.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/a6e89af1-42d2-7b38-c1bd-0b350f292228.png)
この例では「CameraAlpha」変数を0～1で変動させれば、離れていくカットシーンカメラにリスナーが移行していく形になります。
カットシーンが終了し、プレイヤーキャラクターの視点に戻る際も「CameraAlpha」を1～0で変動させればシームレスに戻ります。

変数はタイムラインや**FInterpTo**ノードを使い、滑らかに変化させるとベターです。
![CameraMove_B.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/5838e1ac-512d-4b81-a102-ad257baebc84.png)
![CameraMove_C.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/13b6c49d-b526-bde5-4c4d-1b956be4d7bb.png)




# 視野角による距離ギャップ

極端なシチュエーションですが、このような例も見ていきましょう。
カメラがプレイヤーから離れ、遠くにいる敵をズームし、爆発を起こす様子をとらえます。
<iframe width="560" height="315" src="https://www.youtube.com/embed/Gqwnyfnc1c4?si=OYC6t0oXUl5uwR5D" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

ズームし、敵の姿を間近にとらえているにもかかわらず、アクションのサウンドが小さく、BGMや吹雪の音に負けてしまっています。
これは、ズームをする（視野角を下げる）ことにより起きる現象です。
視野角を下げると遠くのものが近くに見えますが、実際にカメラが近づいているわけではないため、サウンドが遠く感じてしまいます。
![FoV_D.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/abb2b10b-a9a5-e090-dab4-2dcf383b6019.png)
もともとの視野角が低かったところに、視野角を過度に上げた際も反対の現象が起きることがあります。

この現象には、カメラの視野角を取得し、カメラ方向に向かってリスナー座標の補正をかけてあげるとかなりいい感じになります。
カメラからリスナーを射出するイメージです。
![FoV_C.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/9da344f5-11a2-1e54-bb77-c1b4ce0df86a.png)

この処理は、次のようなノードで実装できます。
![FoV_E.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/bcb76186-34c7-acda-56fc-3f15ad6dd45f.png)

実装後のデモを見てみましょう。吹雪の音を殺さず、爆発の効果音も聞こえるようになりました。
<iframe width="560" height="315" src="https://www.youtube.com/embed/HJBaeVfi09E?si=pytN7U5SpkWwokio" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>


一連の動作におけるリスナー位置を視覚化してみました。視野角が下がるにつれ、リスナー位置に補正がかかり、射出されていく様子がよく分かるかと思います。
<iframe width="560" height="315" src="https://www.youtube.com/embed/hHPQ1MazpLI?si=IpnafFQKjO1nhneV" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>



視点やカットシーンにおけるサウンドはさりげない部分ですが、プレイヤー体験にかなり直結する要素でもあります。カメラ、リスナーといった方向からアプローチするサウンドデザインも考慮してみるといいかもしれません。