Wwiseをつかってインタラクティブミュージック(3) Unity組み込み編


[前回](https://qiita.com/dTAT/items/8b990776df1c225f4c5f)まででWwiseのオーサリングツール上でInteractive MusicがつくれたのでこいつをUnityに組み込んでいきたいとおもいます。

## UnityとのIntegration

### Unityプロジェクトを準備

まずUity側の準備をしておきます。
空っぽのNew Projectをつくります。
ここではUniDemoWwiseと名付けました。

![スクリーンショット 2018-01-24 11.03.39.png](https://qiita-image-store.s3.amazonaws.com/0/18557/e5e96c4a-bcfa-e522-148b-97f42f5cd8dc.png "スクリーンショット 2018-01-24 11.03.39.png")

つくれたらとりあえずSceneを保存しておきます。
名前はなんでもいいですがWwiseとつけておきます。
保存できたら一旦Unityをとじます。


### Wwise Launcherで準備

この状態でWwise LauncherのUnityタブに移動すると、現在作成している全てのUnityプロジェクト一覧が確認できます。

![スクリーンショット 2018-01-24 11.06.53.png](https://qiita-image-store.s3.amazonaws.com/0/18557/90bfa583-4a49-7833-adf1-0b26251927c6.png "スクリーンショット 2018-01-24 11.06.53.png")

先ほど作成したプロジェクト(UniDemoWwise)のIntegrate Wwise into Projectボタンをおします
※Unityをひらいたままだとここでエラーになります。

少し待つとWwiseのチェックしょりがおわります。終わったら画面をスクロールします。

![スクリーンショット 2018-01-24 11.12.58.png](https://qiita-image-store.s3.amazonaws.com/0/18557/dccf0f61-2641-adbe-d16b-5b46ac52f418.png "スクリーンショット 2018-01-24 11.12.58.png")

上記のような画面までスクロールしたら、作成ずみのWwiseプロジェクト(プルダウンメニューから選べます)を入力します。
入力したらIntegrateボタンを押します。少しまつと処理が感リョゥして「Operation completed successfull.」になります。完了したら一度「Open in Unity xxx(使用中のUnity ver.)」からUnityを起動しておきます。
![スクリーンショット 2018-01-24 11.22.00.png](https://qiita-image-store.s3.amazonaws.com/0/18557/abbc96bb-964e-fc6b-d0c2-1aea9f7f76d8.png "スクリーンショット 2018-01-24 11.22.00.png")

Wwiseフォルダーが作成されているのを確認したらIntegration完了です。


## Bankの出力

### Eventの作成

IntteractiveMusicを鳴らすEventを作成します。
Wwiseにもどって、画面左上ProjectExplorerのEventタブを選択します。
選択するとEvent作成画面にきりかわるのでDefaultWorkUnitを選択してCreate Empty Eventボタンをおします。
するとDefaultWorkUnitの下にEventがつくられるのでMusicと名付けます。
この名前はあとで重要になってくるので覚えておきます。

![スクリーンショット 2018-01-24 11.35.48.png](https://qiita-image-store.s3.amazonaws.com/0/18557/ed45d5dd-3986-db84-36f7-4fd70605d9fd.png "スクリーンショット 2018-01-24 11.35.48.png")

### EventにPlay Actionを追加

次にMusic Eventを選択すると、右側がMusicEventEditorに切り替わります。図のあたりを右クリックしNewAction>Playを選択します。
※同様の操作はその下のAddボタンからもできます。

![スクリーンショット 2018-01-24 11.44.13.png](https://qiita-image-store.s3.amazonaws.com/0/18557/20e6b431-f67f-98a4-b02a-69f6d80f8272.png "スクリーンショット 2018-01-24 11.44.13.png")

作成できたらAudioタブにもどります。

### PlayActionにContainerを設定

Audioタブに戻ったら先ほどのPlayActionのTargetにMusic Containerをほうりこみます。
これでMusicというEventがおきると、MusicというContainerが再生されるようになります。

![スクリーンショット 2018-01-24 11.49.16.png](https://qiita-image-store.s3.amazonaws.com/0/18557/bf9fc570-5ac8-52df-9215-7d7a228c3c7e.png "スクリーンショット 2018-01-24 11.49.16.png")

### Bankを作成しEventを割当てる

まず上部メニューからLayout>SoundBankからBank編集画面にきりかえます。次に右上のExplorerのEventタブをおしてEvent一覧を表示させます。

次に右中央のSoundBankEditorのNewボタンをおして新しいBankを作成します。名前を入力する画面になるのでここではMusicBankと名付けました。

最後に左下に表示されているEvent一覧から先ほど作成したEventを作成したMusicBankに放り込めばBank作成は完了です。

![スクリーンショット 2018-01-24 11.57.00.png](https://qiita-image-store.s3.amazonaws.com/0/18557/41b5f3bd-188a-8cd1-8136-846914a61840.png "スクリーンショット 2018-01-24 11.57.00.png")

プロジェクトを保存してUnityにもどります。
"プロジェクトを保存して"Unityにもどります。
ここで保存をわすれるとよくわからないエラーに悩まされがちです。

### UnityでSoundBankを生成する

Unityにもどってきたら新しく追加されているWwisePicker画面のGenerate SoundBanksボタンをおします。
※表示されてなかった場合はUnityメニュー>Window>Wwise Pickerを選んで表示させます。

![スクリーンショット 2018-01-24 12.06.39.png](https://qiita-image-store.s3.amazonaws.com/0/18557/1675a21e-a3c6-0e48-cd9a-16727a9363fa.png "スクリーンショット 2018-01-24 12.06.39.png")

## 鳴らす

### コンポーネントを準備する

ついにここまできました！設計などは後回しにしてとりあえず鳴らすことを目指します。とりあえず新規に"BGMPlayerLT.cs"といるスクリプトを作成して以下をコピペしてください。必要なコンポーネントが全部くっつきます。

BGMPlayerLT.cs

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(AkEvent))]
[RequireComponent(typeof(AkBank))]
[RequireComponent(typeof(AkState))]
public class BGMPlayerLT : MonoBehaviour
{
    AkState currentState;
    private void Awake()
    {
        currentState = GetComponent<AkState>();
    }

    public void ApplyCurrentState()
    {
        ChangeState(currentState);
    }
    //文字列直値
    public void ChangeState(string groupName, string stateName)
    {
        AkSoundEngine.SetState(groupName, stateName);
    }
    //AkState参照
    void ChangeState(AkState state)
    {
        AkSoundEngine.SetState((uint)state.groupID, (uint)state.valueID);

    }
}
```

### Introをならす

あとすこしで発音できます！

- Hierarchyに新規GameObjectを作成します
- 新規GameObjectに前述のスクリプトを貼り付けます
- 自動的に複数のコンポーネントが追加されます
- AkStateコンポーネントのStateNameをGameMode/Introにします
- AkBankコンポーネントのBankNameをMusicBankにします
- AkEventコンポーネントのEventNameをMusicにします。

![スクリーンショット 2018-01-24 12.20.53.png](https://qiita-image-store.s3.amazonaws.com/0/18557/de8ed48c-83d8-8dcc-ad39-f6e42c5fc9f0.png "スクリーンショット 2018-01-24 12.20.53.png")

これは、Start時にMusicBankを読み込み、GameMode StateをIntroにした状態にし、MusicというEventを実行するということになります。

UnityEditorを再生するとIntroが再生されるはずです。

### 音を切り替えて遊ぶ

AkStateを切り替えて起動すればそれぞれのStateごとの曲がきけますが、どうせなら切り替えて遊んでみたいとおもいます。

Editorフォルダを作成してください。
そのなかにBGMPlayerLTExtという名前のスクリプトを作成します。
テキストエディタでそのスクリプトをひらき以下のスクリプトに書き換えます。

Editor/BGMPlayerLTExt

```
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using AK.SoundEngine;

[CustomEditor(typeof(BGMPlayerLT))]
public class BGMPlayerLTExt : Editor
{
    string stateName;
    string groupName;
    public override void OnInspectorGUI()
    {
        var t = target as BGMPlayerLT;
        GUILayout.BeginHorizontal("box");
        {
            GUILayout.BeginVertical();
            groupName = EditorGUILayout.TextField("gropuName", groupName);
            stateName = EditorGUILayout.TextField("stateName", stateName);
            if (GUILayout.Button("Stateの直接指定"))
            {
                t.ChangeState(groupName, stateName);
            }
            GUILayout.EndVertical();
        }
        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal("box");
        if (GUILayout.Button("akStateの反映"))
        {
            t.ApplyCurrentState();
        }
        GUILayout.EndHorizontal();
    }
}
```

AkStateが起動後に切り替えても反映されないため、先ほど貼り付けたBGMPlayerLTからその反映をおこなってしまおうというわけです。

![スクリーンショット 2018-01-24 12.47.06.png](https://qiita-image-store.s3.amazonaws.com/0/18557/c1daac3d-641c-47af-7120-f838d2d764f0.png "スクリーンショット 2018-01-24 12.47.06.png")

スクリプトが正しくつくれていれば上図のようなボタンがBGMPlayerLTコンポーネントに追加されているかと思います。再生後にAkStateを選択してから「AkStateの反映」ボタンを押すと、そのAkStateにきりかえることができます。

### ちょっとだけ説明

文字列形式

```
AkSoundEngine.SetState(groupName, stateName);
```

ID形式

```
AkSoundEngine.SetState((uint)state.groupID, (uint)state.valueID);
```

Stateの切り替えは上記の二つのAPIが用意されています。文字列形式のほうはコンポーザー（今回は自分でやりましたが）にStateとそのStateGroup名を聞けばなんとかなります。

IDのほうはWwise側のSoundBankEditorからBenerateすると.hファイルが作成され、その中を見るとIDが書かれているのが確認できます。

Wwise_IDs.h


```
    namespace STATES
    {
        namespace GAMEMODE
        {
            static const AkUniqueID GROUP = 261089142U;

            namespace STATE
            {
                static const AkUniqueID BREAKDOWN = 244770318U;
                static const AkUniqueID INTRO = 1125500713U;
                static const AkUniqueID MAIN = 3161908922U;
            } // namespace STATE
        } // namespace GAMEMODE

    } // namespace STATES
```

なのでいい感じにパースして.hから.csに変更すれば使用が可能です。具体的には

- include文、ifdef文の行をすべてけす
- namespace AKはstatic public class AKIDにかえる
- namespaceはすべてstatic public classにかえる
- static constはすべてconstにかえる
- ファイルをWwise_IDs.hからWwise_IDs.csにかえる

とやってあげればいけます。

## まとめ

オーサリングツール上の操作が非常に大変ですが、SoundBankさえ生成できればエンジニア側はとてもすんなり組み込めることがご理解いただけたかと思います。
Wwiseの機能のほんの一部しかさわっていないので、興味があるかたはmixingなんかにも挑戦されるととても楽しいかと思います。

## 参考

- [公式UnityIntegration]( https://www.audiokinetic.com/ja/library/2016.1.5_5910/?source=Unity&id=main.html )