スポンサーリンク

【Unity】Addressable Asset System の楽チンな使い方を解説【Ver0.3.5対応版】

10/15/2018

Addressable Asset System の使用例

Addressable Asset Systemをどの様に使っているのか?どうすれば効率的なのか?いろいろ考えてしまうことあますよね。
今回は、自分の使い方を紹介します。ぶっちゃけ、使ってみた結果こうなっただけ。たぶんもっといい使い方や管理方法あると思います。参考にしてもらえたら幸いです。

はじめに

Addressable Asset Systemはとっても使い勝手が良いので、自分は、プロジェクト開始時点から組み込みします。
組み込み方は、下記のように実施します。

まず、プロジェクトフォルダの \Packages\Manifest.json  に下記を追加してください。(Unity 2018.2.9)

"com.unity.addressables": "0.3.5-preview",

[window][PackageManager]を開くと確認できます。

その次に設定をします。

引き継ぐコンテンツは通常ないと思いますので、Createを選択します。

Ver0.3.5 の場合、こんな感じで作成されます。

コンテンツの登録

今回は、テキストからPrefabを呼び出す形をとります。
自分はTextデータ から Prefab 呼び出しています。PGに埋め込む以外は、どんな方法をとっても大丈夫と思いますが、構造体を使う事が多いためTextで管理したほうが自分は楽です。
PGに埋め込むのは、あとで後悔するので、やめときましょう。

まず、Textは下記のようにしました。(カンマ区切りで)※最後に’,’をおいておくのが地味にPOINTです。
01-連番
LittleMan-Prefab名
01-X座標
00-Y座標
00-Z座標

Prefabは、Spriteの色違いです。

登録します。

ラベルを付けています。見やすくなり間違えが減ります。あとASSETのアドレスを修正します。
今回は、あえてアドレスを手で変更しています。ちなみに、アドレスの簡略化は下記になります。ラクチンです。

手動で変更する場合は、間違えないように入力しましょう。

プログラムの解説

ネームスペースは下記になります。長いので必須かと

using UnityEngine.AddressableAssets;

付けたタグでコンテンツタイプを絞れます。自分は付けないこと多いです。すみません。

[AssetReferenceLabelRestriction("Text")]
	public string prefabList = "PrefabList";

まず、prefabListを読込みます。後述の処理で利用するため、ロード完了待ちしています。ちなみに何らかの原因でロードできない場合があると無限ループになります。時間などで切るようにしましょう。

ここで非常に重要なお知らせがあります。コンテンツサイズが大きいもの。例えば音楽データなどは、成功になってもすぐには利用できない場合があります。対処は、別途Wait時間を入れる必要があります。iPhone iPadは、注意してください。実機で動作させる場合のみ落ちます。(まじで困る) 

TextAsset dataFile = new TextAsset(); //テキストファイルの保持
	dataFile = null;
	//Assetのロード
	Addressables.LoadAsset(prefabList).Completed += op =>
	{
		//ロードに成功
		Debug.Log("PrefabList:" + op.Result);
		dataFile = op.Result;
	};
	//DL完了待合わせ
	do
	{
		//ロード待ち。ロード不可の場合はずーと抜けない。時間等で切るようにする必要がある。音楽データなどは、これ以外にWaitしないと落ちる場合あります。注意。
		yield return null;
	} while (dataFile == null);

読み込んだTextにより、PrefabをInstantiateします。今回は記載していませんが、実際はOBJECTをプールしています。

var TextLines = dataFile.text;          //テキスト全体
            var textMessage = TextLines.Split('\n'); //テキスト一行に分割
            sampleObject = new GameObject[textMessage.Length]; //オブジェクト保持配列の初期化
            //行数分ループ
            for (int i = 0; i < textMessage.Length; i++)
            {
                var textCell = textMessage[i].Split(',');  //","にて分割

                var cell00 = int.Parse(textCell[0]);
                var cell01 = textCell[1];
                var cell02 = new Vector3(int.Parse(textCell[2]), int.Parse(textCell[3]), int.Parse(textCell[4]));
                //sampleObject.Clear();
                //
                Addressables.LoadAsset<GameObject>(cell01).Completed += op =>
                {
                    //
                    Debug.Log("Prefab" + op.Result);
                    sampleObject[i] = op.Result;
                };
                //DL完了待合わせ
                do
                {
                    //ロード待ち。ロード不可の場合はずーと抜けない。時間等で切るようにする必要がある
                    yield return null;
                } while (!sampleObject[i]);

                //Addressables.Instantiateで生成することもできます。
                sampleObject[i] = (GameObject)Instantiate(sampleObject[i], cell02, Quaternion.identity);
                //今回はそのままにするが使い終わったら処分すること。
            }

配信の準備と変更

上記の設定で実行すると黄色のキャラクタが表示されます。

例えば、アプリを配信後に青いキャラクタに変更したい場合、2つの方法があります。
1.PrefabListを書き換える。Cell02部分のデータを変更する。Assetを配信しなおす。
2.アドレスを差し替える。Assetを配信しなおす。

自分としては、2がおすすめです。1と比較して、間違う可能性が低いからです。

配信に関しては下記を参考にしてください。

さいごに

コンテンツの最新化と入れ替えについては、色々なやり方があると思います。自分は、Addressable Asset Systemにてすべてサーバ配信を利用しアプリを制作中です。
なんでもかんでもPrefabにして配信しようと思いませんが、要はバランス。楽に管理できるとおもいますので、お試しください。

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

namespace Section31Develop
{
    public class Sample : MonoBehaviour
    {
        //Prefab保持
        private GameObject[] sampleObject;

        [AssetReferenceLabelRestriction("Text")]
        public string prefabList = "PrefabList";

        // Use this for initialization
        private void Start()
        {
            StartCoroutine(LoadText());
        }

        private IEnumerator LoadText()
        {
            TextAsset dataFile = new TextAsset(); //テキストファイルの保持
            dataFile = null;
            //Assetのロード
            Addressables.LoadAsset<TextAsset>(prefabList).Completed += op =>
            {
                //ロードに成功
                Debug.Log("PrefabList:" + op.Result);
                dataFile = op.Result;
            };
            //DL完了待合わせ
            do
            {
                //ロード待ち。ロード不可の場合はずーと抜けない。時間等で切るようにする必要がある。
                yield return null;
            } while (dataFile == null);

            var TextLines = dataFile.text;          //テキスト全体
            var textMessage = TextLines.Split('\n'); //テキスト一行に分割
            sampleObject = new GameObject[textMessage.Length]; //オブジェクト保持配列の初期化
            //行数分ループ
            for (int i = 0; i < textMessage.Length; i++)
            {
                var textCell = textMessage[i].Split(',');  //","にて分割

                var cell00 = int.Parse(textCell[0]);
                var cell01 = textCell[1];
                var cell02 = new Vector3(int.Parse(textCell[2]), int.Parse(textCell[3]), int.Parse(textCell[4]));
                //sampleObject.Clear();
                //
                Addressables.LoadAsset<GameObject>(cell01).Completed += op =>
                {
                    //
                    Debug.Log("Prefab" + op.Result);
                    sampleObject[i] = op.Result;
                };
                //DL完了待合わせ
                do
                {
                    //ロード待ち。ロード不可の場合はずーと抜けない。時間等で切るようにする必要がある
                    yield return null;
                } while (!sampleObject[i]);

                //Addressables.Instantiateで生成することもできます。
                sampleObject[i] = (GameObject)Instantiate(sampleObject[i], cell02, Quaternion.identity);
                //今回はそのままにするが使い終わったら処分すること。
            }
        }
        // Update is called once per frame
        private void Update()
        {

        }
    }
}