(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

(:3[kanのメモ帳]


本ブログの運営者kan.kikuchiが個人で開発したゲームです!


SpriteAtlasをプログラムで操作するための拡張クラスSpriteAtlasExtensions【Unity】【SpriteAtlas】【エディタ拡張】


このエントリーをはてなブックマークに追加


この記事でのバージョン
Unity 2018.2.17f1


はじめに

今回はSpriteAtlasをプログラムで操作するための拡張クラス

SSpriteAtlasExtensionsを使ってみようという感じの記事です。



ちなみに以前SpriteAtlasの記事を書いた時にはなかったような気がしたと思ったら、




Unity2018.2から追加されたようです。

新しい 2D Atlas API によって、アトラスの作成・更新を行うカスタムツールを記述できます。



なお、記事中の画像は以下のアセットを使っております。

HD Icons Pack Vol.1 | 2D Icons | Unity Asset Store



SpriteAtlasExtensions

SpriteAtlasExtensionsの使い方を説明する前に、ちょっとした前提の説明です。

まず、SpriteAtlasやSpriteAtlasExtensionsを使うにはU2Dをusingする必要があります。

using UnityEngine.U2D;//SpriteAtlasを使うのに必要
using UnityEditor.U2D;//SpriteAtlasExtensionsを使うのに必要


そして、SpriteAtlasExtensionsは拡張メソッドをまとめたクラス(拡張クラス)なので、

以下のように2通りの実装方法があります。(今回はSpriteAtlasExtensionsを使わない方に統一)

spriteAtlas.Add(new Object[] { sprite });
SpriteAtlasExtensions.Add(spriteAtlas, new Object[]{sprite});


なお、今回はSpriteAtlasに関する説明は省略しているので、

SpriteAtlasの各設定値など、SpriteAtlasについて知りたい場合は以前の記事を参照の事。



 

SpriteAtlasの新規作成とSpriteの追加

SpriteAtlasにSpriteを追加したい場合はAddを使います。

実際にSpriteAtlasの新規作成、Spriteのロードと追加、保存をまとめると以下のような感じになります。

//新しいSpriteAtlasを作成
SpriteAtlas spriteAtlas = new SpriteAtlas();

//SpriteAtlasに追加するSpriteをロード
Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>("Assets/Icons/Armor.png");

//SpriteAtlasにSpriteを追加(一つだけ追加する場合でも配列で指定する)
spriteAtlas.Add(new Object[] { sprite });

//アセットとして保存
AssetDatabase.CreateAsset(spriteAtlas, "Assets/SpriteAtlas/New Sprite Atlas.spriteatlas");

f:id:kan_kikuchi:20190128090648j:plain


なお、AddをしてもSpriteAtlasに元からSpriteを削除したりはしませんが、

既に同じ画像が入っていると重複して追加します。

ただ、重複していてもPack Previewには一つしか表示されず、アプリの容量も増えません


f:id:kan_kikuchi:20190128091200j:plain


ちなみに以前紹介したNonResourcesを使うと、

ディレクトリ内のSpriteを一括で追加出来たりするので便利です。

//新しいSpriteAtlasを作成
SpriteAtlas spriteAtlas = new SpriteAtlas();

//Assets/Icons内にある全てのSpriteをSpriteAtlasに追加
spriteAtlas.Add(NonResources.LoadAll<Sprite>("Assets/Icons").ToArray());

//アセットとして保存
AssetDatabase.CreateAsset(spriteAtlas, "Assets/SpriteAtlas/New Sprite Atlas.spriteatlas");

f:id:kan_kikuchi:20190128100843j:plain



ディレクトリの追加

前項のSpriteと同様にディレクトリを追加する事も可能です。

//新しいSpriteAtlasを作成
SpriteAtlas spriteAtlas = new SpriteAtlas();

//SpriteAtlasに追加するディレクトリをロード
Object iconsDirectory = AssetDatabase.LoadAssetAtPath<Object>("Assets/Icons");

//SpriteAtlasにディレクトリを追加(一つだけ追加する場合でも配列で指定する)
spriteAtlas.Add(new Object[] { iconsDirectory });

//アセットとして保存
AssetDatabase.CreateAsset(spriteAtlas, "Assets/SpriteAtlas/New Sprite Atlas.spriteatlas");

f:id:kan_kikuchi:20190425143824j:plain


なお、ディレクトリを追加しておけば、

ディレクトリの中身が変わっても、自動でSpriteAtlasも更新されるのでとても便利です。


f:id:kan_kikuchi:20190425144019g:plain:w700


SpriteAtlasの更新とSpriteの削除

SpriteAtlasからSpriteを削除したい場合はRemoveを使います。

実際にSpriteAtlasのロード、Spriteのロードと削除、更新をまとめると以下のような感じになります。

//SpriteAtlasをロード
SpriteAtlas spriteAtlas = AssetDatabase.LoadAssetAtPath<SpriteAtlas>("Assets/SpriteAtlas/New Sprite Atlas.spriteatlas");

//SpriteAtlasから削除するSpriteをロード
Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>("Assets/Icons/Armor.png");

//SpriteAtlasからSpriteを削除(一つだけ削除する場合でも配列で指定する)
spriteAtlas.Remove(new Object[] { sprite });

//アセットを最新に更新
AssetDatabase.SaveAssets();


なお、入ってないやつを削除しようとしてもエラーは出ませんし、

重複して入ってる場合は全て削除します。


SpriteAtlasに含まれているSpriteの取得

SpriteAtlasに含まれているSpriteを取得したい場合はGetPackablesを使います。

具体的には以下のような感じ。

//SpriteAtlasをロード
SpriteAtlas spriteAtlas = AssetDatabase.LoadAssetAtPath<SpriteAtlas>("Assets/SpriteAtlas/New Sprite Atlas.spriteatlas");

//SpriteAtlasに含まれている全Spriteの名前をログで表示
foreach (Object item in spriteAtlas.GetPackables()) {
  Debug.Log(item.name);
}

f:id:kan_kikuchi:20190128092001j:plain


Type(MasterやVariant)の設定

MasterやVariantのTypeやそれ関する設定は以下のような感じで行います。

なお、それぞれGetメソッドはないので、現在の状態は取得できないっぽいです。

//SpriteAtlasをロード
SpriteAtlas masterSpriteAtlas = AssetDatabase.LoadAssetAtPath<SpriteAtlas>("Assets/SpriteAtlas/Master Sprite Atlas.spriteatlas");
SpriteAtlas spriteAtlas       = AssetDatabase.LoadAssetAtPath<SpriteAtlas>("Assets/SpriteAtlas/New Sprite Atlas.spriteatlas");

//Variantの設定(falseにするとMasterになる)
spriteAtlas.SetIsVariant(true);

//MasterのSpriteAtlasを設定
spriteAtlas.SetMasterAtlas(masterSpriteAtlas);

//VariantのScaleを設定
spriteAtlas.SetVariantScale(0.5f);

//アセットを最新に更新
AssetDatabase.SaveAssets();

f:id:kan_kikuchi:20190130083111j:plain


なお、SetMasterAtlasでMasterじゃないやつを設定しようとすると、

Cannot set a variant atlas as a master atlas. と警告が出て設定できません。


f:id:kan_kikuchi:20190128095335j:plain


IncludeInBuildの設定

IncludeInBuildの設定にはSetIncludeInBuildを使います。

これもGetメソッドがないので、現在の状態は取得できないっぽいです。

//SpriteAtlasをロード
SpriteAtlas spriteAtlas = AssetDatabase.LoadAssetAtPath<SpriteAtlas>("Assets/SpriteAtlas/New Sprite Atlas.spriteatlas");

//IncludeInBuildを有効にする
spriteAtlas.SetIncludeInBuild(true);

//アセットを最新に更新
AssetDatabase.SaveAssets();

f:id:kan_kikuchi:20190128094814j:plain


Packingの設定を取得、変更

Packingの設定はSpriteAtlasPackingSettingsという構造体が使われています。



そのSpriteAtlasPackingSettingsを取得するにはGetPackingSettingsを使い、

設定するにはSetPackingSettingsを使います。

//SpriteAtlasをロード
SpriteAtlas spriteAtlas = AssetDatabase.LoadAssetAtPath<SpriteAtlas>("Assets/SpriteAtlas/New Sprite Atlas.spriteatlas");

//現在の設定を取得
SpriteAtlasPackingSettings settings = spriteAtlas.GetPackingSettings();

//設定を変更
settings.enableTightPacking = false;

//設定を反映
spriteAtlas.SetPackingSettings(settings);

//アセットを最新に更新
AssetDatabase.SaveAssets();

f:id:kan_kikuchi:20190128093136j:plain


Textureの設定を取得、変更

Textureの設定はSpriteAtlasTextureSettingsという構造体が使われています。



そのSpriteAtlasTextureSettingsを取得するにはGetTextureSettingsを使い、

設定するにはSetTextureSettingsを使います。

//SpriteAtlasをロード
SpriteAtlas spriteAtlas = AssetDatabase.LoadAssetAtPath<SpriteAtlas>("Assets/SpriteAtlas/New Sprite Atlas.spriteatlas");

//現在の設定を取得
SpriteAtlasTextureSettings settings = spriteAtlas.GetTextureSettings();

//設定を変更
settings.readable = false;

//設定を反映
spriteAtlas.SetTextureSettings(settings);

//アセットを最新に更新
AssetDatabase.SaveAssets();

f:id:kan_kikuchi:20190128100354j:plain


プラットフォームごとの設定を取得、変更

プラットフォームごとの設定はTextureImporterPlatformSettingsというクラスが使われています。



そのTextureImporterPlatformSettingsを取得するにはGetPlatformSettingsを使い、

設定するにはSetPlatformSettingsを使います。

//SpriteAtlasをロード
SpriteAtlas spriteAtlas = AssetDatabase.LoadAssetAtPath<SpriteAtlas>("Assets/SpriteAtlas/New Sprite Atlas.spriteatlas");

//Standaloneの現在の設定を取得
TextureImporterPlatformSettings settings = spriteAtlas.GetPlatformSettings("Standalone");

//設定を変更
settings.maxTextureSize = 512;

//設定を反映
spriteAtlas.SetPlatformSettings(settings);

//アセットを最新に更新
AssetDatabase.SaveAssets();

f:id:kan_kikuchi:20190128094505j:plain


ただし、GetPlatformSettingsは存在しなプラットフォーム名を入れてもエラーが出ませんし、

BuildTargetとも名前が違うので、BuildTarget.StandaloneOSX.ToString()のような使い方も出来ません。


なお、実際のプラットフォーム名は以下のページで確認出来ます。

(Unityのバージョンによって変わったりもする)

The valid options for the name are "Standalone", "Web", "iPhone", "Android", "WebGL", "Windows Store Apps", "PS4", "PSM", "XboxOne", "Nintendo 3DS" and "tvOS".




おわりに

SpriteAtlasをプログラムから操作出来るようになったので、かなり使いやすくなりましたね!

なお、SpriteAtlasUtilityなるものもあるようですが、何に使うのかはよく分かりませんでした……。