UnityでJSAMを使って音源管理

(追記: 結局UnityのAddressablesで動的ロードする方が楽だったので，この方法は辞めました)

https://github.com/jackyyang09/Simple-Unity-Audio-Manager

Unityでそれなりの数の音声をオンデマンドで楽に発音させたかったので↑のSimple-Unity-Audio-Manager (制作者のアカウントがjackyなのでJacky's Simple Audio Manager; JSAMみたい)を使ってみた記事です．
GitHub Wikiに載っている使い方がイマイチ要領を得ない感じだったので，ここにまとめておきます．(なお筆者も使い方をちゃんと把握できていないので，無駄な操作をしている可能性がありますし，今のUnityではこれを使わずともイージーに管理できるのかもしれません)

プロジェクトを作るところは省略しておきます．

## JSAMの導入

導入は，READMEに記載してある内容を踏襲して大丈夫です．

1. Window -> Package ManagerでPackage Managerを呼び出します．
![Screenshot0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/9e477523-2627-d575-f1f5-737cfe8bf316.png)
1. 開いたウインドウの"+"を押し， Add package from git URL...を押します．
![Screenshot1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/36dadcb1-0c09-b72a-beb2-2a28bd1cf020.png)
1. URLとして https://github.com/jackyyang09/Simple-Unity-Audio-Manager.git#master を入力し，Addします．
1. なんかダイアログが出るのでOKします．
![Screenshot2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/d1a85436-c66b-faca-a64f-b5e0c95492a2.png)
1. 下のスクショみたいな画像が出たら準備完了です．
![Screenshot3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/b2eb1684-86f5-225a-ba64-273ee66bbfce.png)

## JSAM用GameObjectの設置・ライブラリの初期化

1. Hierarchyで"+"ボタンを押すか右クリックして，Audio内のJSAMからAudio Managerを追加します．
![Screenshot4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/5486839d-1457-5574-ce84-9e9f5957e920.png)
1. オーディオライブラリを初期化します．Window -> JSAM -> Audio Libraryを選択すると，なんかダイアログが出るのでOKします．
![Screenshot5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/d65fbe90-1b9d-e943-6235-4b516243308b.png)
1. 最初はライブラリがないので，開いたウインドウのCreateから適当な名前で作成します．(MyAudioLibraryとしました)
![Screenshot6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/fdca07d0-546f-87e1-2423-b5af4b8b03f6.png)
1. 作成できるとウインドウがこんな感じになります．
![Screenshot7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/7c02171c-eff0-5f1c-7629-524882e9769c.png)
1. Audio Managerのライブラリ参照先にも，↑で作ったライブラリを指定しておきます．
![Screenshot8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/3a39f8b1-c7c0-2b61-a9a1-536b746748a8.png)

ここまででだいたい準備は完了です．

## オーディオファイルの追加と，ライブラリへの登録

1. オーディオファイルを準備します．
1. UnityのAssetに登録します．とりあえず2つ用意しました．
![Screenshot9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/6d493abb-2f9d-e967-bc25-79c18821b5aa.png)
1. Window -> JSAM -> Auio File Wizardを呼び出します．
![Screenshot10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/0951b0fb-7281-7675-1dc1-7bb511c66468.png)
1. 開いたウインドウの"Drag AudioClips here"の部分に，Asset内のオーディオファイルをドラッグ&ドロップします．
![Screenshot11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/4de261d9-4c60-b303-28da-3afffaee9d5a.png)
1. 下の方で音声ファイルの種類や出力先(Asset内にテキトーにJSAMGeneratedみたいな名前でフォルダを作りました)を決めて，Generate Audio File Objectsを押します．
![Screenshot12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/2f64f0f9-4dff-cd12-ae46-466c31dde366.png)
1. するとJSAMがアセットを生成してくれます．この生成物を，Audio Library画面の"List is Empty"のあたりにドラッグ&ドロップします．必要に応じてカテゴリとか設定するといいです．
1. 足したら，"Re-Generate Audio Library"を押します．
![Screenshot13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/e15542b6-34f9-75cb-6abb-0a95a7850573.png)

ここまでで実際にオーディオを使うお膳立てができました．

## スクリプトからのオーディオ再生

1. 適当にスクリプトを作ります．(Asset内で右クリックしてCreate -> C# Script)
1. `using JSAM;`のusingディレクティブを記述します．
1. 音声を再生するには，`AudioManager.PlaySound()`を使います．カッコの中にはEnumでどのファイルを使うかを記述します．EnumについてはJSAMが自動的に生成したEnum用のファイルがいるので，それを参照します．
1. たとえば，起動時にsystem_000として登録したファイルを再生するなら，下のようになります．

```c#
using JSAM;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MyPlayer : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        AudioManager.PlaySound(MyAudioLibrarySounds.system_000);
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}
```

また，たとえば再生させたい音声のenum識別子(?)が外部からstringで来るような場合は，以下のようにして呼び出せます．

```c#
string hoge = "system_000"; // とりあえずここでは手で定義する
AudioManager.PlaySound(
    (MyAudioLibrarySounds)System.Enum.Parse(
        typeof(MyAudioLibrarySounds),
        hoge
    )
);
```

こういう風にしておくと，たとえば案内ロボット用のガイダンスアバターを作るような場合に，外部から今再生すべき音声の識別子を受け取って動的に発話させるという芸当が出来るようになると思います．