読者です 読者をやめる 読者になる 読者になる

オルトプラスエンジニアの日常をお伝えします!

Unity SpritePackerで地味だけど快適になった画像管理について

※この記事は「AltPlus Advent Calendar 2016」の6日目の記事です。

こんにちは。オルトプラスでは主にUnityで2DGUIを作ったりしているid:k1yamaです。

Unityは4.3系から使い始めて2年になりますがその間色々な変化がありました。特にVR周りの進化は目覚ましく、大いに語りたいと思いますが今回は極めて地味なSpritePackerについて書きたいと思います。

(Sprite Packerの設定方法は公式マニュアルをご覧ください)

Sprite Packerってなに?

GUIオーサリングではボタンやパネル等にデザイン素材をアタッチし開発を進めていきますが、単純に進行していくと多数の画像ファイルがアプリケーションに含まれてしまいます。これは描画負荷やファイルサイズの肥大化の一因となり場合によっては大きな問題を引き起こします。

この問題を解決するには複数の画像を一枚の画像にまとめるという手法がよく知られており、前述のUnity4.3系の頃はNGUIに同梱されているAtlasツールを使用していました。(ちなみにWeb制作ではCSS Spriteなどが同種の手法と言えます)

sp.png

複数の画像をひとまとめにする

NGUI Atlas Makerの功罪

しかしNGUIのAtlasツールはいくつかの欠点がありました。

  1. オリジナルファイル、結合ファイルを共にプロジェクト内に持つ
  2. オリジナルファイル、結合ファイルの取り扱いを開発者が意識する必要がある
  3. オリジナルファイルの変更は自動で結合ファイルに反映されない
  4. メタファイルがぶっ壊れると結合ファイルもぶっ壊れる

とりわけ#1の欠点はナンセンスというほかありませんが、NGUIが悪いというよりUnityがこの手の機能を後回しにしたツケだと思っています。

対してSpritePackerでは基本的にオリジナルのみがプロジェクトに含まれ、結合ファイルはキャッシュとして保存されます。

sc3.png

(Library/AtlasCache以下に保存される)

この改善により基本的に結合ファイルは開発者から隠蔽されるので残りの欠点も自動的に解決しています。地味ですが非常に素晴らしいです。

Resourcesに入れられない

そんなSpritePackerですが、一点だけ注意が必要です。SpritePacker対象とする画像はResourcesに格納すべきではありません。

Resourcesに格納すると前述のキャッシュの作成対象ではなくなります。別ディレクトリでキャッシュを作成し、Resourcesへ移動することは可能ですがファイル更新などは無視されます。

Resourcesに格納する場合、ランタイムで動的で読み込むことを意図している場合が多いですが、こうした機能を満たすにはScriptableObjectなどを利用してオリジナルへの参照を保存するのが良さそうです。

また、AssetBundleとして書き出す場合は実態としては結合ファイルが保存されていますがファイルパスベースで読み込むことができるので更に便利です。

bundle.LoadAsset<Sprite>("Assets/Images/Gui/xxxx_button.png")

そういえばパフォーマンスって

冒頭で「描画負荷やファイルサイズが...」と言いつつ開発フローに関する話題ばかりだったので一応パフォーマンスに触れておきます。

今回のサンプルではiOS、Unity5.4.1.p1、画像枚数90枚で以下の結果となりました。

オリジナル/SP アプリサイズ SetPath Call Draw Call
オリジナル 88.4MB 4 96
Sprite Packer 72.1MB 4 68

まずアプリサイズが20%減少と大きな効果を生んでいます。

次にSetPathCallに変化はありませんが、DrawCallは30%程減っています。実際に問題になるのはSetPathCallだとUnite等でも指摘されていますが、今回は絶対数が小さいこともあり効果を得ることはできませんでした。次回はもっと絶対数が大きくなる環境で試してみたですね。

ちなみにAssetBundleを使用した場合も同じようにPathCall,DrawCallが減少します。

開発環境の成熟に関して

パフォーマンスに関しては以前と根本的な変化はないので、個人的にはワークフローの改善をアピールしたいところです。

Unityは5系になってからInstantiateに親のTransformを渡せるようになったり、SendMessageに替わるメッセージングシステムを導入したり、MultiSceneEditingを備えたりと地味だけど嬉しい機能が随時追加されています。

VR関連機能も熱いですが、こういった「開発者を応援するぜ!」という気概にあふれた機能追加を続けるUnityにはこれからも期待していきたいですね。