シンプルなサウンドマネージャー (Unity)

# おことわり
この記事には、[新しい版 (GitHub)](https://github.com/tetr4lab/SoundManager)が存在します。

# 前提
- Unity 2019.4.5f1
- 使用に際して、C#でスクリプトを書く必要があります。
    - C#に触りたくない場合は、Boltでも大丈夫です。
        - Bolt Visual Scripting 1.4.12 で確認済み
- UIの操作音など、音源の位置が画面に固定されている場合に適しています。

# できること
- BGMとSEの番号を指定して再生できます。
    - BGM
        - 最大同時再生数は2で固定です。(クロスフェード用)
        - あらかじめ、インスペクタで、フェードイン、フェードアウト、インターバルの時間を指定します。
        - 再生はループします。
    - SE
        - あらかじめ、インスペクタで、最大同時再生数を指定します。
        - 再生時に、「同じ音でも重ねて鳴らす」、「同じ音が鳴っていたら止めてから鳴らす」、「同じ音が鳴っていない場合だけ鳴らす」ことが選択可能です。
        - 再生はループしません。
- BGMとSEの音量を独立して設定できます。
- 全体の一時的なミュートが可能です。

# アセットの入手 (GitHub)
ダウンロード ⇒ [SoundManager.unitypackage](https://github.com/tetr4lab/SoundManager/raw/Unity2019.4/SoundManager.unitypackage)
[ソースはこちらです。](https://github.com/tetr4lab/SoundManager/tree/Unity2019.4)

# 導入と設定
- プロジェクトにアセットをインポートしてください。
- シーンの適当なオブジェクトに、スクリプト`Sound.cs`をアタッチしてください。
- インスペクタで、`Sound Effect Clip`と`Sound Music Clip`のSizeを必要なだけ増やし、オーディオクリップを設定してください。
- 必要に応じてパラメータを調整してください。

![コメント 2020-07-26 214625.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365845/18d361cc-4516-56f0-2839-09e6a6e96ba2.png)

|項目|説明|初期値|
|:---|:---|---:|
|Sound Effect Max|SE同時再生数|5|
|Sound Effect Initial Volume|SE初期音量|0.5|
|Sound Music Initial Volume|BGM初期音量|0.5|
|Sound Music Fade In Time|BGMフェードイン時間|0|
|Sound Music Fade Out Time|BGMフェードアウト時間|3|
|Sound Music Interval Time|BGMインターバル時間 (フェードアウト時間が0でなく負数なら重なる)|0|
|Sound Effect Clip|SEオーディオクリップ|-|
|Sound Music Clip|BGMオーディオクリップ|-|

# 使い方
### SEを再生する
#### 同じSEでも重ねて鳴らす
```cs:
Sound.Effect = number;
```
- 空きのチャネル(AudioSource)で再生します。
- 空きがない場合は、最も古くに再生開始されたチャネルの再生を止めて使います。

#### 同じSEが鳴っていたら止めてから鳴らす
```cs:
Sound.StopAndEffect = number;
```
- 以下と同じ処理です。

```cs:
Sound.EffectStop = number;
Sound.Effect = number;
```

#### 同じSEが鳴っていない場合だけ鳴らす
```cs:
Sound.EffectIfNot = number;
```
- 既に同じ音を再生中であれば、新たに再生しません。

#### 最後に再生中の音番号を得る
```cs:
var number = Sound.Effect;
```
- 何も再生されていない場合は、`Sound.Silent`が得られます。

#### 指定したSEを止める
```cs:
Sound.EffectStop = number;
```
- 複数チャネルで再生している場合は、最も古い再生チャネルだけが止まります。

#### 全てのSEを止める
```cs:
Sound.Effect = Sound.Silent;
// or
Sound.EffectStop = Sound.Silent;
```

#### SE音量を設定する
```cs:
Sound.EffectVolume = volume;
```
- 正規化された値(0～1f)を設定します。取得もできます。

#### 登録されているSE数を得る
```cs:
var count = Sound.EffectCount;
```

### BGMを再生する
```cs:
Sound.Music = number;
```
- インスペクタで設定されたフェードイン、フェードアウト、インターバルの時間(秒)を勘案して曲を再生します。
    - 既に再生中の曲の場合は、単に再生を継続します。
    - 別の曲を再生中の場合は、まず、再生中の曲がフェードアウトします。
        - フェードアウト時間が0なら即座に止まります。
        - 負値は指定できません。
    - 次に、インターバル時間だけ、次の再生開始を待機します。
        - 負値の場合は、フェードアウト中に遡って待機を終えます。
    - 待機を終えると、指定された曲のフェードインを開始します。
        - フェードイン時間が0なら即座に既定音量で再生されます。
        - 負値は指定できません。
    - 再生中でない場合は、即座にフェードインが開始されます。
    - クロスフェード中に新たな再生指示があった場合は、以下の特例処理を行います。
        - 前の(フェードアウト中の)曲が再生指示された場合は、2曲のフェード方向が切り替わります。
        - フェードアウト・イン中のどちらとも異なる第3の曲が再生指示された場合は、再生中だった2曲の内で音量の大きい方をフェードアウトさせ、音量の小さい方は即座に停止して次の曲の開始シーケンスに移行します。
- 例
    - 全ての時間が0なら、即座に切り替わります。
    - 全ての時間が1なら、前の曲が1秒でフェードアウト、1秒無音で、次の曲が開始され1秒でフェードインします。
    - フェードインとフェードアウトが3でインターバルが-1だと、前の曲が3秒でフェードアウトし、その終了1秒前に次の曲が再生を開始して3秒でフェードインします。フェードアウト開始からフェードイン終了までは5秒になります。


#### 再生中の曲番号を得る
```cs:
var number = Sound.Music;
```
- 再生されていない場合は、`Sound.Silent`が得られます。

#### BGM音量を設定する
```cs:
Sound.MusicVolume = 0.5f;
```
- 正規化された値(0～1f)を設定します。取得もできます。

#### 登録されているBGM数を得る
```cs:
var count = Sound.MusicCount;
```

#### BGM再生を止める
```cs:
Sound.Music = Sound.Silent;
```
- フェードアウト時間の設定が0でない場合は、フェードアウトします。
- フェードアウト時間が0の場合は即座に止まります。

### 一時的に全ての音を消す、戻す
```cs:
Sound.Mute = true; // 一時的に音を消す
Sound.Mute = false; // 音を戻す
```
- 音が出ないだけで、既存の再生は継続しますし、新たな再生も有効です。

---

以下の素材を使わせていただきました。
どうもありがとうございました。

- SoundEffects: ©効果音ラボ https://soundeffect-lab.info/
- Music: ©魔王魂 https://maoudamashii.jokersounds.com/