0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Unity】元々おかれているSpriteをメモリから解放する【MemoryProfiler】

Posted at

はじめに

ゲームを制作する以上、Spriteを表示する機会は多い
今一度メモリから解放されるタイミングを調査してみた

試す

SpriteRendererによって参照される3000*3000の画像を用意した
スクリーンショット 2025-12-12 0.00.58.png

MemoryProfilerで確認すると、当然Allocateされていることがわかる
スクリーンショット 2025-12-12 0.02.48.png

そこで以下のコードを用意する

ObjectDestroyer.cs
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

[Serializable]
public class DestroyContext
{
    public Key Key;
    public GameObject GameObject;
}

public class ObjectDestroyer : MonoBehaviour
{
    public List<DestroyContext> destroyContexts;

    void Update()
    {
        var keyboard = Keyboard.current;
        if (keyboard == null) return;

        foreach (var context in destroyContexts)
        {
            if (keyboard[context.Key].wasPressedThisFrame && context.GameObject != null)
            {
                Destroy(context.GameObject);
            }
        }
    }
}

そしてこのスクリプトをシーンに配置する
スクリーンショット 2025-12-12 0.08.03.png

Spaceを押してシーン上のオブジェクトがDestroyされたことを確認してから、MemoryProfilerを再度確認する
スクリーンショット 2025-12-12 0.14.41.png
Allocateされたままであることを確認できる

シーンを遷移できる以下のスクリプトを作成する

SceneLoader
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;

[Serializable]
public class SceneLoadContext
{
    public Key Key;
    public string SceneName;
}

public class SceneLoader : MonoBehaviour
{
    [SerializeField] private List<SceneLoadContext> sceneLoadContexts = new();

    private void Update()
    {
        foreach (var context in sceneLoadContexts)
        {
            if (Keyboard.current[context.Key].wasPressedThisFrame)
            {
                SceneManager.LoadScene(context.SceneName);
                break;
            }
        }
    }
}

同様に設定して、シーンを遷移させる
スクリーンショット 2025-12-12 0.23.02.png

すると画像はアンロードされていることが確認できる
スクリーンショット 2025-12-12 0.27.25.png

つまり、シーンに最初から配置されているSpriteは、シーンのアンロード時に同時にアンロードされる

これは、Unity側でシーンの依存アセットとしてSpriteが自動的にパックされているためである
https://docs.unity3d.com/6000.3/Documentation/Manual/build-content-output.html

また、以下のようなスクリプトを用意してみる

using UnityEngine;
using UnityEngine.InputSystem;

public class ResourceUnloader : MonoBehaviour
{
    void Update()
    {
        if (Keyboard.current[Key.T].wasPressedThisFrame)
        {
            Resources.UnloadUnusedAssets();
            Debug.Log("UnloadUnusedAssets");
        }
    }
}

これをシーン上に配置してTを押すと、メモリから解放されていることを確認できる
スクリーンショット 2025-12-12 0.39.48.png

Resources.UnloadUnusedAssets();を使うと、シーンに紐づいてロードされたアセットについても、参照されていないアセットを解放できる

まとめ

SpriteRendererで参照しているSpriteは、オブジェクトをDestroyしただけではメモリからは解放されない
シーンを遷移してアンロードすると、そのシーンに最初から配置されていたSpriteはシーン依存アセットとしてまとめてアンロードされる
それ以外にも、Resources.UnloadUnusedAssets();を呼び出すと、シーン由来でロードされたアセットで会っても、参照が切れていればメモリから解放できる

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?