Unity の Resources を使って、テクスチャを動的に読み込んで、使用後にメモリを解放する方法を書いていきます。
動作確認
以下のゲームで動作を確認しています。
注意点
Unity のチュートリアル には「Resources を使用しないでください。」と書かれています。
※ チュートリアルの「3.1. Best Practices for the Resources System」で「Don't use it.」。
Resources を使うメリット
Resources を使うメリットは以下の通りです。
- 画像を読み込むまで、メモリ消費を抑えることができます。
- 画像のメモリを解放することができます。
1. Resources フォルダの準備
Assets の下に Resources フォルダを作成して、読み込む画像を置きます。
2. SpriteRenderer の作成
Resources フォルダの画像をヒエラルキーにドラッグ&ドロップして、SpriteRenderer を作成します。
今回は4つの画像を追加しています。
必要に応じて SpriteRenderer の Position を調節しておきます。
3. Sprite の削除
インスペクターで、SpriteRenderer の Sprite を削除します。Sprite の値をクリックして Delete を押すと削除できます。
削除すると、画面の画像も消えます。
Sprite を削除しないと、ゲームの起動時に画像がメモリに展開されます。なので、今回は全て削除しました。
4. スクリプト作成
スクリプトを作成して、以下の内容を保存します。Enter を押すと画像を読み込んで、再度 Enter を押すとメモリを解放します。
Controller.cs
using UnityEngine; public class Controller : MonoBehaviour { public SpriteRenderer[] renders; string[] paths = { "marisa", "pache", "reimu", "sakuya" }; bool loaded = false; void Update() { if (Input.GetKeyDown(KeyCode.Return)) { if (loaded) Unload(); else Load(); } } void Load() { for (int i = 0; i < renders.Length; i++) { renders[i].sprite = (Sprite) Resources.Load(paths[i], typeof(Sprite)); } loaded = true; } void Unload() { foreach (SpriteRenderer sr in renders) { Resources.UnloadAsset(sr.sprite.texture); sr.sprite = null; } loaded = false; } }
画像の読み込み
画像を読み込む際は、Resources フォルダの画像のパスを指定します。
Resources.Load(paths[i], typeof(Sprite));
メモリの解放
メモリを解放する際は、null の代入がポイントになります。
Resources.UnloadAsset(sr.sprite.texture); sr.sprite = null;
5. スクリプトの有効化
空の GameObject を作成して、スクリプトをアタッチします。
スクリプトの public変数 renders
には、先ほどの SpriteRenderer を全て紐づけておきます。
6. 動作確認
ゲームを起動して、Enter で動作確認します。
画像読み込み後
プロファイラのテクスチャは 220 で、21.0MB でした。
メモリ解放後
テクスチャは 216、5.0MB になりました。
ゲーム起動直後は、この値に近かったです。