メモリ削減手法
- ここでは Creator で実施したメモリ削減手法を記す
WebGL では GC の発生タイミングは任意に発生させることはできない
- Android/WebPlayer の場合には GC.Collect() を実行することで発生させることができた
- WebGL ではブラウザの GC に任せるため、任意のタイミングで実行はできない
- https://blogs.unity3d.com/jp/2016/12/05/unity-webgl-memory-the-unity-heap/ external_link
-
Calling GC.Collect() has no effect on Unity WebGL.
- そのため、メモリ使用量に関しては気を配る必要がある
WWW クラス利用後は Dispose() を実行して、Resources.UnloadUnusedAssets を実行する
- www クラスでテクスチャやオーディオの読み込みをした際にメモリが消費される
www.texture
とかwww.GetAudioClip
とか
- Unity 内部の実装の詳細は不明だが、www クラスで取得したものは、他の変数に移して、Dipose(メモリ破棄) し、 Unity 側にリソースの解放を依頼する(Resources.UnloadUnusedAssets)
- サンプルコード
storeData [key] = (T)(object)www.texture; www.Dispose(); yield return Resources.UnloadUnusedAssets();
-
実際のコミットログ
-
storeData という変数に Texture を読み込み、解放しているコード
Resources.UnloadUnusedAssets();
で yield return をしているのは、処理完了を待つようにするため(詳細はわからないが、念のため)
テクスチャは 2の累乗で読み込む
- OpenGL の挙動らしいが。(NPOT / POT で調べるといいかも)
- POT (2の累乗) にした方がメモリ使用量としては親切
- 多分 Unity 内部で下手すると、サイズが2の累乗じゃないとき、2の累乗計算して、そこにマッピングしているから、という可能性はある
- サンプルコード(ここでは 2048/2048 でテクスチャを作成して、 www から画像を読みだしてマッピングしている)
Texture2D texture = new Texture2D(2048, 2048, TextureFormat.DXT5Crunched, false); www.LoadImageIntoTexture(texture);
読み込んだテクスチャは圧縮する
- WebGL 環境の場合に限るが、画質の多少の劣化を犠牲にして圧縮を利用することができる
- png などのアルファ値がある場合、 DXT5 を選ぶとよい(他はググって調べてくれ)
- サンプルコード (www.texture external_link を直接読み込んでいた個所を、以下のようにして圧縮を行い、省メモリ化した)
// DXT5Crunched の空のテクスチャを用意 Texture2D texture = new Texture2D(2048, 2048, TextureFormat.DXT5Crunched, false); // ここでテクスチャを読み込み www.LoadImageIntoTexture(texture); // テクスチャ圧縮 texture.Compress(false); // 圧縮後のテクスチャを割り当て storeData[key] = (T)(object)texture; // 読み込みは終わったので Dispose() www.Dispose()
プラットフォーム依存のテクスチャ設定を利用して、メモリ使用量を削減する
- これは Unity にデフォルトで用意されている機能を使う
- Unity ではプラットフォーム毎(Android/WebPlayer/WebGL ...) 毎にテクスチャの圧縮設定を変えることができる
- 内部プロジェクトで使用した際は WebGL の時だけ、DXT5Crunched を適用するようにした(元々は TrueColor とかだったかな)
- タイトル画面はさすがに劣化がカッコ悪かったのでやらなかった