AssetBundleManagerを使ってAssetBundleからTextファイルを読み込む

この記事は[TCU-CTRL場外乱闘 Advent Calendar 2017](https://adventar.org/calendars/2322#list-2017-12-11) 12日目の記事です
#環境
- Unity2017
- [AssetBundleManager](https://www.assetstore.unity3d.com/jp/#!/content/45836)

#はじめに
ゲーム開発においてキャラクターの台詞や、敵のパラメーターなどを全てソースコード内に記述することは後の変更が難しくなるため、テキストファイルとして保存しておき読み込む方法がよくあるパターンです。
Unityにおいてもそのパターンは当てはまります。しかし、Unityのファイル読み込みでググるとResourcesフォルダを使った方法が多く出てきます。
Resourcesフォルダを用いたファイル読み込みはシンプルですが、アプリの起動時間やビルド時間が伸びたりコンテンツの更新が難しくなるなどの理由から[公式チュートリアル](https://unity3d.com/jp/learn/tutorials/temas/best-practices/resources-folder)では推奨されていません。

その為今回はAssetBundleからTextファイルを読み込む方法を検証します。

#AssetBundleManagerの準備
AssetStoreからAssetBundleManagerをインポートします
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/222915/93b39f04-23e3-9ef2-ca17-6e3e1056a1e7.png)

インポートが終了したら、Assets->AssetBundlesからSimulation Modeがオンになっていることを確認します
![2017-12-12 (1).png](https://qiita-image-store.s3.amazonaws.com/0/222915/81f69c3f-341f-5f24-7bda-d9f222d4baca.png)

#AssetBundleの用意
読み込むためのAssetBundleを用意します。
今回はTestData.txtを作成しました。
適当なTextファイルを作り、右下に有るAssetLabelからAssetBundleNameを設定します。

![2017-12-12 (4).png](https://qiita-image-store.s3.amazonaws.com/0/222915/f053326c-853c-375b-5c38-609be8151a38.png)

今回は新しく`test/data`というAssetBundleNameを作成し設定しました。

![2017-12-12 (5).png](https://qiita-image-store.s3.amazonaws.com/0/222915/2aaf1fab-b20c-5645-eadb-63b00d1712ab.png)

#AssetBundleのビルド
AsettBundleNameを設定したら、Assets->AssetBundlesからBuildAssetBundlesを選択してビルドを行います。
これでAssetBundleが生成されました。
![2017-12-12 (7).png](https://qiita-image-store.s3.amazonaws.com/0/222915/c842d820-2968-ba80-d3ad-8fa08af94274.png)

#AssetBundleManagerをシングルトンにする
AssetBundleManagerによるファイルの読み込みはゲーム内の様々な場所で行われるのでシングルトンにしておくと楽ができます。
テラシュールブログさん([Unityで少しだけ高速なシングルトン](http://tsubakit1.hateblo.jp/entry/20140709/1404915381))のシングルトンをもらってきて継承し、ファイルを読み込むためのメソッドを持つクラスを作ります。
`LoadASync<T>(string assetBundleName, string assetName, Action<T> callback)`のassetBundleNameは2つ前の節で付けた名前、assetNameはファイルの名前になります。
このクラスをシーン上の適当なGameObjectにアタッチしておきます。


```C#:AssetBundleManagerSingleton
public class AssetBundleManagerSingleton : SingletonMonoBehaviour<AssetBundleManagerSingleton>
{
    IEnumerator Start()
    {
        yield return StartCoroutine(Init());
    }

    IEnumerator Init()
    {
        var request = AssetBundles.AssetBundleManager.Initialize();
        if (request != null)
            yield return StartCoroutine(request);
    }

    /// <summary>
    /// 非同期でAssetBundleからAssetを読み込む
    /// </summary>
    public void LoadASync<T>(string assetBundleName, string assetName, Action<T> callback)
        where T : UnityEngine.Object
    {
        StartCoroutine(LoadASyncAssetBundle<T>(assetBundleName, assetName, callback));
    }

    IEnumerator LoadASyncAssetBundle<T>(string assetBundleName, string assetName, Action<T> callback)
        where T : UnityEngine.Object
    {

        var request = AssetBundles.AssetBundleManager.LoadAssetAsync(assetBundleName, assetName, typeof(T));

        if (request == null)
            yield break;
        yield return StartCoroutine(request);

        T asset = request.GetAsset<T>();

        callback(asset);
    }

}
```

#Textファイルを読み込んで表示する
Textファイルの読み込みを開始するためのButtonと、読み込んだテキストを表示するためのTextをシーンに配置します。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/222915/40956ac9-9482-ad0b-2b6c-78bd5c0b0dd2.png)

そして以下のようなクラスを作成して、Buttonにアタッチします。
LoadASyncは非同期でAssetBundleを読み込むので、読み込んだデータの受取はコールバックで行います。

```C#:main
public class main : MonoBehaviour
{

    [SerializeField] Button readButton;
    [SerializeField] Text text;

    private void Start()
    {
        readButton.onClick.AddListener(() => Onclick());
    }

    void Onclick()
    {
        AssetBundleManagerSingleton.Instance.LoadASync<TextAsset>("test/data", "TestData", (textAsset) =>
        {
            text.text = textAsset.text;
        });
    }

}
```

#結果
しっかりとAssetBundleからジュースハゲコピペが読み込まれているのが確認できます。
![b.gif](https://qiita-image-store.s3.amazonaws.com/0/222915/6d8d15ea-69b7-39f2-32ad-57001f8e768e.gif)

#感想
今回はAssetBundleからTextファイルを読み込む方法を検証しました。
実はAssetBundleのことをまともに調べたのは今回が初めてで、結果としてTextファイルの読み込みには成功しましたが、正直まだよくわかってないことが多いのでこれからも好きあらば調べていきたいところです。
てか公式のAssetBundleManager情報が[これ](https://docs.unity3d.com/jp/current/Manual/AssetBundles-Manager.html)しか見つからなかったので結構辛い。リファレンスどこ？？？？

次回は[まくらんく君(@cap_pepsi)](https://twitter.com/cap_pepsi)です。よろしくお願いします