[Resources.LoadのBestPracticesの検証(3,複数回読んでみる]
(https://qiita.com/tessa256/items/ae5cc80aa0a5d6306858)
の続き
Resources.LoadしたUnityEngine.Objectを
Resources.UnLoadの引数にしただけではダメということが分かってきたので
ここで改めてUnityAPIドキュメントを見てみる。
・参照しているAssetのみに対して呼び出すことができる。
・解放されたオブジェクトは無効になる。
ということでResources.Loadされたものに対して対で呼ばれるメソッドではないようなので
今回は下記ソースコードで解放のテストをしてみる。
using System;
using System.Collections;
using UnityEngine;
public class ResourcesLoaderByType : MonoBehaviour
{
public enum LoadType
{
Order = 0,
Sprite
};
// LoadTypeの定義順に合わせること
private static readonly System.Type[] _LoadTypeTable = new System.Type[]
{
typeof(UnityEngine.Object),
typeof(Sprite)
};
public event Action<UnityEngine.Object> OnLoadComplete;
[SerializeField, Header("ResourcesLoadのPathを指定")]
private string ResourcesLoadPath;
[SerializeField, Header("指定したAssetの型を指定")]
private LoadType AssetType;
private UnityEngine.Object Asset;
private IEnumerator Start()
{
var request = Resources.LoadAsync(ResourcesLoadPath, _LoadTypeTable[(int)AssetType]);
yield return request;
Asset = request.asset;
if (OnLoadComplete != null)
OnLoadComplete(Asset);
}
private void OnDestroy()
{
if (Asset == null)
return;
switch (AssetType)
{
case LoadType.Order:
Resources.UnloadAsset(Asset);
break;
case LoadType.Sprite:
{
var targetObject = Asset as Sprite;
if (targetObject == null)
break;
Resources.UnloadAsset(targetObject.texture);
Resources.UnloadAsset(targetObject);
}
break;
}
}
}
ざっくり解説すると
1.ResourcesLoadPathに指定されたAssetをAssetTypeで指定された形式で非同期で読み込む。
2.読み込みが完了するとOnLoadCompleteが呼ばれる。
3.解放するときは指定したTypeにダウンキャストして参照しているAssetに対してUnloadAssetする。
挙動を見るために今回はSpriteのみ
注意:
・ロード中に破棄されたらどうする?等の考慮がなかったり(そもそもResourceRequestにキャンセルがない。
・ダウンキャストそのものは失敗の危険性がある。
これで例のごとくProfilerでMemory項目を見ていく。
あらかじめProfileでLoadで増えたものをメモっておきそれを
Unloadで呼ぶ分には動いてる模様。
ただ
Resources.LoadがType指定で何を読み込んでいるのかを見るためには
・Profileによる目視
・Resources.Loadのソースの中身を見る
ぐらいしか思いつかないのでAssetの中でも
・画像
・サウンド
・Prtefab、component
を必要になったらLoadして必要なくなったら解放する
という用途で使用するにはかなりリスキーだと感じる。
なによりUnloadが複数呼ばないといけないのは気持ち悪い
特にPrefab、componentはspriteやaudio sourceがついている状態で
できているのが普通なのでくっついているAssetをUnloadなんてやろうものなら
解放対象のAssetを検索して消すなんてコードを足すなんてやるべきでないしやりたくない。
このメソッドの用途はここは公式の推奨に従い
・最善の方法は使わないこと
使うとしても
・ScriptableObjectを使った設定ファイルの読み込み
・最小限必要かつ変更のないデータベースのダンプの読み込み
ぐらいだろう。
ただプラットホームごとにResourcesフォルダのAssetの扱いが
ちがうのでそこはしっかり調べてから使った方がよいだろう
(マルチプラットフォームだったら使わない方がよい