こんにちわ、Unityエンジニアのオオバです。

SpriteAtlasからSpriteを取得する方法の解説をします。

var sp = SpriteAtlas.GetSprite("spriteName");  

名前が事前にわかっているSpriteは
カンタンに取得できます。

こういった場合はどうすれば良いでしょうか。

解説していきます。

この記事の内容

EditorSpriteUtilityを使うとカンタンゲット

抜き出したいSpriteAtlasを渡すだけで
Spriteのリストを取得する機能を作りました。

// atlasインスタンスを渡すだけ  
List<Sprite> spriteList =  
    EditorSpriteUtility.GetSpriteList(atlas);  

パッケージ提供していますので、
インストールするとすぐに使えます。

EditorSpriteUtilityのインストール方法

以下のURLをUnity PackageManagerから追加
https://github.com/baobao/EditorSpriteUtility.git?path=Assets/EditorSpriteUtility  

または、

manifest.jsonに1行追加してください
"info.shibuya24.editorspriteutility": "https://github.com/baobao/EditorSpriteUtility.git?path=Assets/EditorSpriteUtility"  

SpriteAtlasExtensionsが便利

Editor専用ですが、
Unity公式SpriteAtlasの拡張メソッド
SpriteAtlasExtensionsが便利です。

今回の実装で役立ったのはGetPackablesメソッド。
SpriteAtlasに格納されたSpriteを取得できます。

ただし落とし穴があります。

SpriteAtlasはフォルダ指定可能な罠

SpriteAtlasを使うとき、
Spriteが格納されたフォルダを指定しませんか?

SpriteAtlasにフォルダ指定した状態

【Unity】SpriteAtlasから名前のわからないSpriteを取り出す方法_0

フォルダを指定した場合、
GetPackablesに格納されるのは
DefaultAsset(フォルダ)です。

フォルダだった場合は、
その中身を検索する必要があるのです。

AssetDatabaseでフォルダ内のSpriteを検索

フォルダだった場合、
以下のコードでフォルダの中のSpriteリストを取得します。

var objs = atlas.GetPackables();  
foreach (var o in objs)  
{
    // フォルダだった場合  
    if (o is DefaultAsset)  
    {
        // フォルダのパスを取得  
        var dirPath = AssetDatabase.GetAssetPath(o);  
        // フォルダ内のSpriteのGUIDリストを取得  
        var spriteGUIDs = AssetDatabase.FindAssets($"t:sprite", new string[] { dirPath });  
        // GUIDからSpriteリストを取得  
        var spriteList = spriteGUIDs.Select(AssetDatabase.GUIDToAssetPath)  
            .Select(AssetDatabase.LoadAssetAtPath<Sprite>).ToList();  
  1. フォルダのパスを取得
  2. フォルダ内のSpriteのGUIDリストを取得
  3. GUIDからSpriteリストを取得

このような手順です。

Texture2DをSpriteとして取得する

もう1つのパターンが
SpriteがSpriteAtlasに
直接セットされている場合です。

SpriteAtlasに直接Spriteがセットされている状態

【Unity】SpriteAtlasから名前のわからないSpriteを取り出す方法_1

この場合GetPackablesメソッドは
Texture2D型を返却します。

ほしいのはSprite型のリスト。
Texture2DをSpriteとして受け取る必要があるのです。

🚫キャスト不可

感覚的にTexture2D→Spriteへ
キャストできそうではありますが、
クラスの互換がないためできません。

🚫Texture2DをSpriteにキャスト不可
// キャスト不可  
var sprite = (Sprite)texture2d;  

Spiriteとして再ロードする

Texture2DからSpriteを取得するためには、
Textue2Dファイルのパスを使って
Spriteをロードします。

var objs = atlas.GetPackables();  
foreach (var o in objs)  
{
    // SpriteAtlasにSpriteが直接セットされている場合の分岐  
    if (o is Texture2D)  
    {
        // Texture2Dのパスを取得  
        var texture2dPath = AssetDatabase.GetAssetPath(o);  
        // Texture2Dのパスを使ってSpriteとしてロードする  
        var sp = AssetDatabase.LoadAssetAtPath<Sprite>(texture2dPath);  

このようにTexture2Dのパスから
Spriteを吸い出すことができます。

まとめ

UIや2Dゲームでよく使用するSpriteAtlas。
SpriteAtlasから全Spriteを取得する方法を解説してきました。

オススメはオオバ作EditorSpriteUtility.GetSpriteList
使うのが手っ取り早いでしょう。

その部分のソースコードをダウンロードして
使うでも良いと思います。全体で50行ほど。

📚参考サイト : EditorSpriteUtility/EditorSpriteUtility.cs at main · baobao/EditorSpriteUtility · GitHub
↑こちらからダウンロードできます。


フォローすると UIデザイナー力の上がるTwitter やってます!
今日から使えるテクニックを発信中。
ぜひフォローしてみてください!
👉フォローはこちら!

最後まで読んでいただきありがとうございました!
すばらしいSpriteAtlasライフをお過ごしください。

オススメ記事
検証環境