【Unity】柔軟に効果音を再生できる SEPlayer

# 概要

柔軟に効果音を鳴らせる SEPlayer を作りました[（以前作った SEManager の紹介記事はこちら）](https://qiita.com/Yamara/items/4caf72e20daea180197d)
SEManager に比べて柔軟性が上がり、3Dにも対応しています。

``` 使用例.cs
[SerializeField] AudioClip clip;

private void Start()
{
    // 効果音を再生
    clip.PlayOneShot();

    // 効果音の再生を試みる。 また transform.position の位置で鳴らす
    clip.Play(priority: 127).SetPos(transform.position);

    // 効果音を transform に追従させ、ピッチと音量を変更して1秒遅れで再生
    clip.Play(transform, delay: 1f).SetPitch(0.8f).SetVolume(0.5f);

    // 全ての効果音を一時停止
    SEPlayer.Pause();

    // clip を再生している AudioSource が有ったら再生を停止する
    SEPlayer.GetAudioSourcesAll().FirstOrDefault(a => a.clip == clip)?.Stop();
}
```

# コード

https://github.com/yamara-mh/CodeStorage/blob/main/Codes/SEPlayer.cs

https://github.com/yamara-mh/CodeStorage/blob/main/Codes/SEPlayerSettings.cs

AudioMixerManager の導入も必要です。[紹介記事はこちら](https://qiita.com/Yamara/items/6300a93ed624248fbd84)

https://github.com/yamara-mh/CodeStorage/blob/main/Codes/AudioMixerManager.cs

AudioSource を便利に扱える拡張メソッド```AudioSourceEx```も使うと、より簡潔に書けます。

https://qiita.com/Yamara/items/6e853c1d268083400fef

### 導入方法

1. Addressables と UniTask を導入（しなくても少し修正すれば使えます）
2. SEPlayer, SEPlayerSettings, AudioMixerManager（と AudioSourceEx）を配置
3. ```Assets/Create/ScriptableObject/new SEPlayerSettings```から SEPlayerSettings を生成
4. Addressables に「SEPlayerSettings」という名前で登録
5. SEPlayer の Generate() にある、Settings の代入処理をコメントアウトと書き換えて、発生するエラーを修正

# 機能説明

## SEPlayerSettings について

SEPlayer の設定ができる ScriptableObject です。

|プロパティ|説明|
|-|-|
|Default Audio Source Prefab|Play() 用に生成する AudioSource を設定できます。<br>null の場合、AddComponent で AudioSource を生成します。|
|Max Audio Source|Play() 用に生成する AudioSource の数です。<br>この数を超えて再生する場合、再生を試みる効果音を含めて最も優先度の低い効果音の再生を中断します。|
|InitalXXX|Play() 用の AudioSource を生成した際に設定するパラメータです。<br>既存のパラメータを参考に追加・削除する事もできます。|
|DefaultXXX|効果音の再生直前に設定するパラメータです。<br>既存のパラメータを参考に追加・削除する事もできます。|

## 再生系の関数

|関数|説明|
|-|-|
|AudioClip.Play()|効果音を再生します。<br>戻り値が AudioSource なので各種パラメータを変更できます。|
|AudioClip.TryPlay()|優先度を考慮して効果音の再生を試みます<br>他は Play() と同じです。|
|AudioClip.PlayOneShot()|PlayOneShot 用の AudioSource で効果音を再生します。<br>負荷は軽いですが、パラメータの変更はできません。<br>引数の OneShotMode で再生する AudioSource を指定できます。|

### Play() に設定できる引数

|引数|型|説明|
|-|-|-|
|transform|Transform|効果音が終了するまで AudioSource を transform の座標に移動させ続けます。|
|ended|Action\<AudioSource original, AudioSource instance\>|AudioSource の再生が終了または、優先度の関係で中断されたときに実行されます。<br>タプルの original には DefaultAudioSourcePrefab , instance には利用後の AudioSource が入っています。instance に original の値を代入など|
|delay|float|再生を遅延します。|

### パラメータ変更の留意点

Play() で取得できる AudioSource は再利用されるので、パラメータを変更した際は ended を利用して元に戻しましょう。
なお再生終了時、利用した AudioSource に SEPlayerSettings の値 DefaultXXX を代入して、再利用可能にしています。

``` 例.cs
clip.Play(ended: args => args.instance.SetBypassSettings(false, false, false))
    .SetBypassSettings(true, true, true)
    .SetPitch(0.8f).SetVolume(0.5f);
```

## 停止系の関数

|関数|説明|
|-|-|
|SEPlayer.Stop()|全ての効果音を停止します。|
|SEPlayer.Pause()|全ての効果音を一時停止します。|
|SEPlayer.UnPause()|全ての効果音の一時停止を再開します。|

引数の```oneShotAll```を false にすると、PlayOneShot 用の AudioSource が除外されます。
そこから引数の```params AudioMixerGroupEnum[]```で、適応したい AudioSource を指定できます。

## その他

|関数|説明|
|-|-|
|SEPlayer.GetAudioSourcesAll()|Play() で利用される AudioSource を全取得します。|
|SEPlayer.ChangeAudioSourcesCount()|Play() で利用される AudioSource の個数を変更します。|