6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Unity パフォーマンス改善 学んだ事まとめ

Last updated at Posted at 2018-10-11

個人で勉強しているうちは気にしていなかったのですが、実務として扱うようになるなり勉強が必要となりました。

Unityのプロファイラーで学んだことを下記へまとめていきます。

##動的に生成したTextureとSpriteはしっかり管理しよう!

参考:
動的に生成したTextureとSpriteはしっかり管理しよう!
【Unity】アセットのUnloadとDestroyについて

タイトルの通り、Texture2DとSpriteを動的に生成する処理は、コンポーネントしているGameObjectがDestroy(破棄)されてもTexture2DとSpriteが残ってしまいます。

使わないリソースを破棄する方法は例えば、

  1. Resources.UnloadUnusedAssets()を使用する
  2. foreachで個別にDestroyする
ことが挙げられます。

###Resources.UnloadUnusedAssets()
Unityスクリプトリファレンス

使用していないアセットをアンロードします。

ヒエラルキーにあるゲームオブジェクト(スクリプトコンポーネントを含む)群で総なめして、アセットが使用されていないかを判断します。静的変数も調査されます。

しかし、スクリプト実行スタックは 探索されない ため、アセットはスクリプトスタックの中からのみ参照されるため解放され、必要であればそのプロパティーやメソッドのひとつが使用されるときに再び読み込まれます。これはメモリ上で修正されたアセットの場合は特に扱いに注意が必要です。アセットのガベージコレクションがトリガーされる前に EditorUtility.SetDirty を忘れずに呼び出しをするべきです。

Resources.Unloadは,例えばProfilerのMemoryの項目でAssetsと表示される項目をアンロードできます。

それ以外の項目、NotSavedやSceneMemoryに格納される、インスタンス化したオブジェクト群はResources.Unloadでは開放する事が出来ません。これは、実行時に値を変更したMeshやMaterialや動的に生成したTexture、Prefab等が該当します。

###foreachで個別にDestroyする

NotSavedやSceneMemoryの項目に格納される、インスタンス化したアセットに関しては、個別にDestroyで開放します。

CreateTexture.cs
public class CreateTexture : MonoBehaviour {

    public int m_createCount = 100;
    private List<Texture2D> texture2dList = new List<Texture2D>();
    private List<Sprite> spriteList = new List<Sprite>();

    // Use this for initialization
    void Start () {
        for(int i =0; i < m_createCount; i++)
        {
            Texture2D texture2D = new Texture2D(1000, 1000);
            Sprite sprite = Sprite.Create(texture2D, new Rect(0.0f, 0.0f, 1000, 1000), Vector2.zero);
            texture2dList.Add(texture2D);
            spriteList.Add(sprite);
        }
        DestroyTexture2D();
    }
    
    private void DestroyTexture2D()
    {
        Destroy(this.gameObject);
    }

    private void OnDestroy()
    {
        Resources.UnloadUnusedAssets();
    }
}

##特定アセットがメモリから破棄されているか知る方法
68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3235363731372f39383534663630352d656631652d306131632d356431312d3935333438623365353031332e706e67.png

Memoryプロファイラーを使用します。
ゲームを実行→アセットがロードしているか知りたいタイミングでTake Smaple: Editorを押す。
→Scene Memoryの中から目当てのアセットを探す。
私の場合は、Texture2Dの画像でした。

例えば、画面遷移後にもう一度TakeSampleし、この画像がなくなっていたならば、意図通り破棄できたと確認できます!

##ガベージコレクション

ガベージコレクションは、不要になったメモリ領域を自動的に解放する機能です。
Unityのガベージコレクションはあまり高性能ではないらしい。

【Unity】Unity におけるゲーム開発でガベージコレクションを最適化する(翻訳)

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?