2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SpriteAtlasをScriptableObjectにして使うアイデア

Posted at

この記事は思いつきを書いたものです。

普段TexturePackerなどでPackしたSpriteAtlasを読み込む時どうしてますか?

Resources.LoadAllだったりAssetBundle.LoadAllAssetsだったりで読んできて
Sprite[]から探して読んだりしていませんか?
そこで、今回思いついたのがSpriteをすべてScriptableObjectにして、
使う時はScriptableObjectを読み込むという方法です。

使用したアセット

今回Serialize可能なDictionaryであるSerializeDictionaryを利用しています。
https://github.com/neuecc/SerializableDictionary

こちらの絵素材を使用しています。
https://pipoya.net/sozai/terms-of-use-of-free-materials/

ScriptableObjectの作成


using System;
using System.Linq;
using SerializableCollections;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;

#endif

[Serializable]
public class StringSpriteDictionary : SerializableDictionary<string, Sprite>
{
}

[CustomPropertyDrawer(typeof(StringSpriteDictionary))]
public class ExtendedSerializableDictionaryPropertyDrawer : SerializableDictionaryPropertyDrawer
{
}

public class SpriteAtlasAsset : ScriptableObject
{
#if UNITY_EDITOR
    [MenuItem("Tools/CreateSpriteAtlasAsset")]
    static void CreateSpriteAtlasAssetInstance()
    {
        var spriteAtlas = CreateInstance<SpriteAtlasAsset>();
        spriteAtlas.atlasCache = new StringSpriteDictionary();
        foreach (var obj in Selection.objects)
        {
            var assetPath = AssetDatabase.GetAssetPath(obj);![SpriteAtlasInspector.PNG](https://qiita-image-store.s3.amazonaws.com/0/16088/daacc87f-3ef1-fb1c-7495-804062243688.png)

            var sprites = AssetDatabase.LoadAllAssetsAtPath(assetPath).OfType<Sprite>().ToArray();
            foreach (var sprite in sprites)
            {
                spriteAtlas.atlasCache.Add(sprite.name, sprite);
            }
        }

        AssetDatabase.CreateAsset(spriteAtlas, "Assets/SpriteAtlas.asset");
        AssetDatabase.Refresh();
    }
#endif

    [SerializeField] StringSpriteDictionary atlasCache = new StringSpriteDictionary();


    public Sprite GetSprite(string spriteName)
    {
        return atlasCache[spriteName];
    }
}

このコードを作成しmultipleなTextureを選択してToolsのCreateSpriteAtlasAssetを押すと
Assets直下にScriptableObjectが作成されます。
作られたSpriteAtlasのScriptableObjectのInspectorを見ると選択したTextureに含まれるSpriteが読まれます。
SpriteAtlasInspector.PNG

使用する時

using UnityEngine;
using UnityEngine.UI;

public class ScriptableTest : MonoBehaviour
{

    [SerializeField] SpriteAtlasAsset spriteAtlas;
    [SerializeField] Image image;

    void Start()
    {
        image.sprite = spriteAtlas.GetSprite("majo_1");
    }
}

上記のようなMonobehaviorを継承したクラスを作り、Inspectorで先程作成したScriptableObjectを貼ります。
実行後して確認してみると以下のようになりました。

game.PNG

結果

ScriptableObjectを作る手間は増えるが、ScriptableObjectをInspectorで直接設定可能で
はじめからDictionaryで保持することが可能だったりと便利になったのではないでしょうか?

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?