この記事でのバージョン
Unity 2017.1.0f3
はじめに
Unity 2017から新たにSpriteAtlasなるものが追加されました。
今までもSpriteをパックする(一つの画像にする)機能としてSpritePackerがありましたが、
ちょっと使ってみた感じ、SpriteAtlasの方がかなり良さげです。
SpritePackerと違い、SpriteAtlasというファイルが実際に出来るので分かりやすく、
何よりResources内でも使える(SpritePackerは使えない)というのが一番の利点でしょうか。
なお、そもそもSpriteをパックする(一つの画像にする)利点は、単純に言えば処理が軽くなる事です。
以下の画像はパックしたものとしてないものの比較で、
パック後はSetPass calls(描画回数)が減っているのが分かると思います。
という事で今回は、SpriteAtlasを使ってみた系の記事です。
なお、記事中の画像は以下のアセットを使っております。
HD Icons Pack Vol.1 | 2D Icons | Unity Asset Store |
SpriteAtlasの作成
まず、Create - Sprite AtlasからSpriteAtlasのファイルを作成します。
あとは生成したSpriteAtlasのObjects for PackingにパックしたいSpriteを指定するだけ。
Spriteの指定はフォルダ単位でも可能ですし、
Pack Previewを押すとパック結果を見ることも出来ます。
ただし、パックしたい画像はあらかじめTextureTypeをSpriteにする必要があります。
なお、Resources内にSpriteAtlasと元の画像の両方を入れてしまうと、
画像が重複して追加され、容量が増えるみたいなので、SpriteAtlasだけをResourcesにいれましょう。
SpriteAtlasの設定
次にSpriteAtlasの設定項目についてです。
Type
Typeは基本的にMasterで問題ありません。
もう一つのType、Variantは異なる解像度に対応する時用で、
他のSpriteAtlas(Master)を元にScaleを指定して複製する感じで使います。
Include in Build
常にビルドに含めるかどうかを設定する項目で、
基本的に有効で問題ありません。
Asset Bundleを介してSpriteAtlasを使う場合には無効にした方が良いようです。
Allow Rotation
パックする際に回転を許容するかどうかの設定で、
基本的に有効で問題ありません。
なお、Atlas内で回転するだけなので、取り出して使う時は元の状態で使えます。
Tight Packing
パックする際に詰め込むかどうかの設定で、
基本的に有効で問題ありません。
なお、Atlas内では各画像が重なっているように見えますが、取り出して使う時は元の状態で使えます。
Read/Write Enabled
Textureの情報の読み書きができるかどうかの設定で、
基本的に無効で問題ありません。
Textureをプログラムから操作したい時は有効にする必要がありますが、
使用メモリが倍になるので注意が必要です。
Generate Mip Maps
画像が遠くにある時に表示する、小さい画像(Mip Maps)を生成するかどうかの設定で、
基本的に無効で問題ありません。
有効にすると遠くのモノの解像度を下げる事で、負荷を下げる事が出来ますが、
容量が増えるので注意が必要です。
Filter Mode
フィルタの設定で、基本的にPointですが、
拡大した時に補完して欲しい場合はBilinear OR Trilinearを使います。
Max Texture Size
パックした画像の最大サイズを設定します。
基本値は2048ぐらいで、あまり大きすぎると表示できないスマホもあるので注意が必要です。
もし、この設定値より大きくなりそうな場合は自動で分割してくれますが、
違う画像にまとめられたモノを表示した場合はSetPass calls(負荷)は減りません。
なお、分割された各画像の確認は右上のプルダウンから行う事ができます。
Compression
圧縮形式の設定です。
基本はNoneで良いですが、容量を減らしたい時は適宜他の設定にします。
もちろん圧縮するほど画像は劣化するので、注意が必要です。
SpriteAtlasの取得
では生成&設定を終えたSpriteAtlasを実際に使ってみましょう。
SpriteAtlasは他のファイル同様、Resources.Loadで取得でき、
SpriteAtlasのGetSprite(画像の名前)を使う事でSpriteを取得出来ます。
/*SpriteAtlasを使うには using UnityEngine.U2D; が必要*/ //Resources直下にあるWeaponAtlasという名前のSpriteAtlasを取得 SpriteAtlas weaponAtlas = Resources.Load<SpriteAtlas>("WeaponAtlas"); //WeaponAtlasに含まれているaxe2というSpriteを取得 Sprite sprite = weaponAtlas.GetSprite("axe2");
もちろん、Inspectorから設定して使う事も可能です。
//Inspectorから設定して使う [SerializeField] private SpriteAtlas _weaponAtlas = null;
また、GetSpritesでSpriteAtlasに含まれる全Spriteの取得が可能です。
ただし、返り値として取得するわけではなく、引数にSpriteの配列を渡し
その中に全Spriteが追加される感じです。
//WeaponAtlasに含まれるSpriteの数を取得 int spriteCount = _weaponAtlas.spriteCount; //spriteの空の配列を作成、サイズはAtlasに含まれるSpriteの数 Sprite[] spriteArray = new Sprite[spriteCount]; //spriteArrayに全Spriteを設定 _weaponAtlas.GetSprites(spriteArray);
なお、SpriteAtlasのGetSprite(s)で取得したSpriteの名前には、(Clone)が付きます。
おわりに
SpritePackerのResources内では使えないという致命的な問題が無くなり、
だいぶ使い易くなったSpriteAtlasですが、
GetSpriteで取得する際に文字列で指定する必要があったり、全Spriteの取得が面倒だったり、
いくつか改善の余地がありそうです。
ということで次回は、このあたりを良い感じにする記事を予定しております!
-----------------------------追記
書きました!
参考