3D音源の距離減衰で各サウンド音量の取得【Unity】

成果物

  • サウンド(色がついているオブジェクト)ごとに距離に応じた再生音量を取得

Repository

github.com

Demo(Unity Room)

unityroom.com

実装

AudioSouceとListenerの挙動

Unityで3D音源を鳴らすときには、基本的に AudioSourceのAudioClipに任意のサウンドデータをアタッチしてサウンドを鳴らすようになっています。

AudioSourceを設定した後に AudioListenerがアタッチされているオブジェクトを移動させると以下のようにAudio SourceのInspctorで現在のListenerと3D Sound設定した関数の交わっている個所を見ることができます。

Audio Sourceの距離減衰のAnimationCurveの取得

設定したAnimationCurveを取得するには、AudioSource.GetCustomCurve から取得します。

docs.unity3d.com

しかし、LogarithmicやLinearの場合は、こちらの関数を使うことができません(仕様?)。そのため、今回は以下のようにして Linerと Customを判別して AnimationCurveを返す関数を作成しました。

        private AnimationCurve GetAnimationCurve()
        {
            return animationCurve = _audioSource.rolloffMode switch
            {
                AudioRolloffMode.Linear => AnimationCurve.Linear(_audioSource.minDistance, 1, 1, 0),
                AudioRolloffMode.Custom => _audioSource.GetCustomCurve(AudioSourceCurveType.CustomRolloff),
                _ => animationCurve
            };
        }

ここの注意なのですが、Customで返ってくるAnimatinCurveは0-1のサイズに取得称されるため、計算する際に0-1の範囲で計算する必要があります。

プレイヤーと発生しているサウンドの距離からなっている音量を取得する

先ほど取得した Audio SourceのAnimation Curveから任意の点の音量値を取得するには、AnimationCurve.Evaluate を使います。

docs.unity3d.com

この関数は、引数に time(今回の場合は、なっているAudioSource Object とプレイヤーの距離) が必要になるため Vector3.Distance(AudioSource.position,Player.position) で 距離を計算します。

その後、取得した Animation Curveが0-1に丸め込みされるため 距離 / MaxDistanceで 0-1の範囲に収まるように変換します。

        public float GetAudiValue(Vector3 playerPosition)
        {
            var distance = Vector3.Distance(transform.position, playerPosition);
            return animationCurve.Evaluate(distance / _maxDistance);
        }

このときの MaxDistance は 、Audio Sourceの Max Distanceを _audioSource.maxDistance から取得してきた値になります。

docs.unity3d.com

後は 適当にViewスクリプトを作って取得した各サウンドの音量値を表示させてあげれば、以下のようにできます。