ゲーム中の複数キャラボイス管理テクニック(ADX for Unity)

# はじめに

開発を進めていくと、プレイアブルキャラクターの追加のようにリソースのバリエーションを増やしたくなります。そこで問題になってくるのが、似たような種類のサウンドが増えることによる管理コストの増加です。
本記事では、複数のキャラクターボイスを切り替えて扱う実装例をもとに、再生管理を容易にする手法を紹介します。

この記事は「ゲーム中の複数キャラボイス管理テクニック(ADX for Unity)」のUnity版です
[https://qiita.com/SigRem/items/6a4d46c8138ebd09b0bd](https://qiita.com/SigRem/items/6a4d46c8138ebd09b0bd)

# 前提

## 動作確認環境

Windows 10 Home 20H2
Unity 2020.3.27f1  + ADX LE Unity SDK 3.06.03
CRI ADX LE Tools for Windows 3.46.09

## 前提記事

CRI ADX導入方法や基本的な操作については以下の記事を参照して下さい。

Unityのサウンド機能をADXで強化する

[https://qiita.com/Takaaki_Ichijo/items/16e6501fc07f5b3b3377](https://qiita.com/Takaaki_Ichijo/items/16e6501fc07f5b3b3377)

# やること

- AtomCraftでキャラクターごとにキューシートを作成
- Unityにインポート
- テストシーン作成
- テスト再生

# 実装

## AtomCraft側の作業
まずは、管理するボイスデータの設定を行います。
ADXにおいて、再生用のデータはUnityとは別のツール「AtomCraft」を使い設定を行います。
その手順については、元の記事（UE4向け記事）の同名の項と同じになりますので省略しています。
本記事の手順を試す場合は、まず元の記事の[該当項目](https://qiita.com/SigRem/items/6a4d46c8138ebd09b0bd#atomcraft%E5%81%B4%E3%81%AE%E4%BD%9C%E6%A5%AD)を進めてから本記事を進めてください。
UE4版との違いとして1点、「Atomキューシートバイナリのビルド」画面で、一番左下のオプション「UnityAssets出力」にチェックを入れるのを忘れないようにして下さい。

## Unity側の実装

### キューシートのインポート

AtomCraftからエクスポートしたファイルをインポートします。

### シーン上にないサウンドデータを再生できるスクリプトを作成する

[導入編の記事](https://qiita.com/Takaaki_Ichijo/items/16e6501fc07f5b3b3377)ではシーンに直接Atom Cueを置いて再生していましたが、配置していない音声も再生できるよう、その場でデータをロードして再生する仕組みを取り入れます。

以下のVoiceManagement.csを作成します。

```VoiceManagement.cs
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;

public class VoiceManagement : MonoBehaviour
{
    private CriAtomExAcb acb;
    private CriAtomExPlayer atomExPlayer;

    private void Start()
    {
        atomExPlayer = new CriAtomExPlayer();
    }

    public async void LoadCueSheetAsync(string targetName)
    {
        CriAtomCueSheet criAtomCueSheet = CriAtom.GetCueSheet(targetName);

        if (criAtomCueSheet == null)
        {
            criAtomCueSheet = CriAtom.AddCueSheet(targetName, targetName + ".acb", "");
            while (criAtomCueSheet.IsLoading)
            {
                await Task.Yield();
            }
        }

        acb = criAtomCueSheet.acb;
    }

    public void PlaySE(string cueName)
    {
        if (acb == null) return;
        if (!acb.Exists(cueName)) return;

        atomExPlayer.SetCue(acb, cueName);
        atomExPlayer.Start();
    }

}
```

重要なのはCriAtom.AddCueSheetメソッドで、引数に指定したCueシートを登録し使える状態にします。今回の実装例では第一引数（Cueシート名）と第二引数（パス）が同じになる設定にしているため指定を簡易的にすませています。インポートフォルダやacbファイル名を変更している場合、第二引数にはAssets/StreamingAssetsフォルダからの相対パスを指定して下さい。

### テスト用シーンを作成する

以下の画像のようなシーンを準備します。
![テスト用シーン](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2576800/12bc658a-870c-7361-8857-3720f43c99fd.png)


- CriWareLibraryInitializer、CriWareErrorHandler
    - 基本コンポーネント、GameObject＞CRIWAREから作成
- VoiceManagementという名前の空のGameObject
    - 前項で作成したVoiceManagement.csコンポーネントをアタッチ
    - CRIAtomコンポーネントをアタッチ
        - ACFFileにはVoiceManagement.acf（インポートしたファイル名）を設定
- UIのButton4つ
    - GridLayoutGroupを利用するときれいに並ぶ
    - OnClickイベントに以下のメソッドを登録する
        - VoiceManagement.LoadCueSheetAsyncを２つ
            - 設定値はCV_Fighter、CV_Rival
        - VoiceManagement.PlaySEを２つ
            - 設定値はCV_Damage、CV_Explore

### テストの実行

ここまで出来たら忘れずに保存を行い、実行します。
まずPlaySEを押してみます。実行直後はCueシートを読み込んでいないため効果音は鳴りません。
次にどちらかのLoadボタンを押してからPlaySEを押します。Cueシートが正常に読み込まれていれば対象の音が鳴ります。
最後に押していない方のLoadボタンを押してPlaySEを押します。Cueシートが切り替わり、同じボタンでも違う音が鳴ることが確認できます。
またLoadボタンを押すごとにCRIAtomコンポーネントにCueが読み込まれていることが確認できると思います。

## 活用例

今回は複数キャラクターボイスの管理方法について紹介しました。他にもMOBのサウンドセットや武器ごとのSE切り替えなどに使える可能性があります。
なお似たような機能として「セレクタ」というものがあります。こちらは同じCue内に音声データが含まれるため、切り替えの頻度が高いものはこちらのほうが向いています。

参考：ゲームの状況に合わせて効果音にバリエーションを by ADX2 for UE4

[https://qiita.com/SigRem/items/2c1f497ebf0e981dd43c](https://qiita.com/SigRem/items/2c1f497ebf0e981dd43c)