【Unity】Addressable Asset System の楽チンな使い方を解説【Ver0.3.5対応版】
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を選択します。
コンテンツの登録
今回は、テキストからPrefabを呼び出す形をとります。
自分はTextデータ から Prefab 呼び出しています。PGに埋め込む以外は、どんな方法をとっても大丈夫と思いますが、構造体を使う事が多いためTextで管理したほうが自分は楽です。
PGに埋め込むのは、あとで後悔するので、やめときましょう。
まず、Textは下記のようにしました。(カンマ区切りで)※最後に’,’をおいておくのが地味にPOINTです。
01-連番
LittleMan-Prefab名
01-X座標
00-Y座標
00-Z座標
登録します。
ラベルを付けています。見やすくなり間違えが減ります。あと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()
{
}
}
}