C#
Unity

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

この記事はTCU-CTRL場外乱闘 Advent Calendar 2017 12日目の記事です

環境

はじめに

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

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

AssetBundleManagerの準備

AssetStoreからAssetBundleManagerをインポートします
キャプチャ.PNG

インポートが終了したら、Assets->AssetBundlesからSimulation Modeがオンになっていることを確認します
2017-12-12 (1).png

AssetBundleの用意

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

2017-12-12 (4).png

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

2017-12-12 (5).png

AssetBundleのビルド

AsettBundleNameを設定したら、Assets->AssetBundlesからBuildAssetBundlesを選択してビルドを行います。
これでAssetBundleが生成されました。
2017-12-12 (7).png

AssetBundleManagerをシングルトンにする

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

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

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

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

感想

今回はAssetBundleからTextファイルを読み込む方法を検証しました。
実はAssetBundleのことをまともに調べたのは今回が初めてで、結果としてTextファイルの読み込みには成功しましたが、正直まだよくわかってないことが多いのでこれからも好きあらば調べていきたいところです。
てか公式のAssetBundleManager情報がこれしか見つからなかったので結構辛い。リファレンスどこ????

次回はまくらんく君(@cap_pepsi)です。よろしくお願いします