sh1’s diary

プログラミング、読んだ本、資格試験、ゲームとか私を記録するところ

Unity Legacy Sprite Packer と Simple Sprite Packer の更新

古い記事で sprite をインポートする際は、Simple Sprite Packerプラグインを使用していました。ここ数年の間、Unity をあまり触れることができなかったのですが、久しぶりにアプリを作る際に sprite の読み込みでこの Assets を使用すると obsolete の表示が出てくるようになっていました。

warning CS0618: 'TextureImporter.spritesheet' is obsolete: 'Support for accessing sprite meta data through spritesheet has been removed. Please use the UnityEditor.U2D.Sprites.ISpriteEditorDataProvider interface instead.'

そもそも 2017 年ごろから従来の Sprite Packer の利用が推奨されなくなりつつあったようで、2023 年の現在はプロジェクトに対して下記のオプションを設定しないと警告が出る状態のようです。デフォルトでは Sprite Atlas を使えということになっていて、その Sprite Atlas も V1 と V2 のバージョンがあり、V2 のほうがもちろん新しく、長らく Experimental になっていましたが Unity 2022.1 では Sprite Atlas V2 がデフォルトになったようです。

おそらく Simple Sprite Packer は、この Legacy にあたるのだと思います。単に TextureImporter.spritesheet のメソッドが obsolete になっているだけの恐れもあります。(どちらにしても Assets の置き換えはしたい)

プロジェクト設定 (Project Settings) -> Editor -> Sprite Packer -> Mode を見てみると、確かに「Sprite Atlas V2 - Enabled」になっていますね。

現在では、従来の Sprite Packer の仕組みは Legacy Sprite Packer という呼ばれ方をされていました。(もう Project Settings -> Editor -> Sprite Packer の Mode の設定でも非表示になってしまった)

整理すると、現在は Sprite Packer という名前は、いまも Project Settings に登場するけど、これは「複数の画像を(ひとつの画像に)パッキングする機能」のことを指して使われていると思います。以前の Sprite Packer は、Legacy Sprite Packer として名前を分けていたこともあり、また、現在は非推奨になっている上に Sprite Atlas が標準になっている。

それから Sprite Atlas も V1 と V2 があり、現在は V2 が標準的になっているので、基本は Sprite Atlas V2 を使おう、という流れの感じだと思います。

そもそも、Sprite をパッキングする理由は画像を1枚のデータにしておけば、データの読み込みが軽くなるからで、具体的には(主に)Stats の SetPass calls(描画回数)に影響しています。Legacy Sprite Packer から Sprite Atlas に更新された経緯は、1枚の画像データにパッキングするという目的は同じでも、多機能化(パラメーター化)して、ファイル管理上の違いもあって Resources フォルダー内でも利用可能になったみたいです。(ただし Addressable 推奨)

Sprite Atlas V2

Sprite Atlas V2(V1 も Legacy Sprite Packer に比べると、およそ同じ)の扱い方は、というよりも sprite の扱い方はそれほど難しくありません。要点は Sprite Atlas は、複数の画像をひとつにまとめたデータファイル(のようなもの)を用意すること、です。それが Sprite Atlas ファイル、ということになります。

Sprite Atlas ファイルは、いくつでも用意することが可能です。ここがパッキング化する面白いところで、なんでもかんでもたくさんの画像をひとつの Sprite Atlas ファイルにパッキングすると、今度は巨大なデータファイルをメモリに置くことになるので、逆に負荷となります。

なので、ある程度のところで Sprite Atlas ファイルを複数用意します。option などのコモンと言える画像でまとめてみたり、同じ scene で使うなど、共通化するポイントを整理しましょう。

最初に Sprite Atlas ファイルをプロジェクトに追加します。Create -> 2D -> Sprite Atlas で作成することができます。

Sprite Atlas ファイルを選択して Inspector の Object for Packing にまとめる sprite ファイル、または、sprite ファイルの入ったフォルダーを追加します。

そのあと「Pack Preview」ボタンを押下すれば Sprite Atlas ファイルの完成。簡単です。

動作確認

Scene に適当なオブジェクトを追加して以下のサンプルコードを書いたコンポーネント Sample を追加します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.U2D;

public class Sample : MonoBehaviour
{
    [SerializeField]
    private SpriteAtlas _Atlas;

    // Start is called before the first frame update
    void Start()
    {
        Debug.Log($"SpriteCount = {_Atlas?.spriteCount ?? 0}");

        var sprite = _Atlas.GetSprite("r");

        Debug.Log(sprite.name);
    }
}

プログラムを起動したタイミングで Sprite Atlas のデータ数を調べたり、sprite を取得してみたサンプルです。以下のようなログが出力されました。

上図の例は SpriteMode が single のファイルを3つ、Multiple のファイルを2つ、Sprite Atlas に追加しました。Multiple はそれぞれ5つ、9つに分割されています。 なので、

 {
\begin{equation}
3+5+9=17
\end{equation}
}


という計算になるみたいです。sprite ファイルはファイル名で取得することができるので、Multiple のスライスされたデータはスライスされた後の名前を指定してやりましょう。

このあたりで拡張メソッドを用意して取得しやすくする考えや、遅延ロードする、といった手法(考え方)があるみたいです。

遅延ロードの考え方は面白いです。

参考