ゲーム開発チーム「丸ダイス」の開発ブログです! 公式サイトはこちら

【Unity】Grid By Cell Size でのSprite EditorのスプライトシートSliceを自動でやる方法

ドット絵のゲームではこんな感じのスプライトシートをアニメーションに使います。 f:id:marudice:20210505110243p:plain

通常はこんな具合に

f:id:marudice:20210505110801p:plain:w400

テクスチャのImport Settingsから48x48でBottomが原点~みたいな設定でSliceしてスプライトシートを作るのですが・・・

f:id:marudice:20210505110949p:plain:w300

まぁたくさんあって大変ですね・・。毎回同じ設定で良いので自動でやりたい。

答えはほぼこちらのフォーラムにあって、おなじみのAssetPostProcessorエディタ拡張を使います。

Cell Size 48x48
Pivot Bottom Center
ほか ドット絵っぽい設定
対象 "Assets/Texture/Sprite"以下のテクスチャのみ

例えばこんな感じなら、 以下のコードをAssets/Editor以下に入れれば、対象フォルダに画像を入れるだけで自動でSliceまでやってくれます!

GridSpritePostProcessor.cs

using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class GridSpritePostProcessor : AssetPostprocessor
{
    public override uint GetVersion()
    {
        return 1;
    }

        // 特定のパス以下のみ処理する
    private bool IsAssetGridSprite() { return assetPath.StartsWith("Assets/Texture/Sprite"); }

    public void OnPreprocessTexture()
    {
        if(IsAssetGridSprite())
        {
            TextureImporter importer = (TextureImporter)assetImporter;
            importer.textureType = TextureImporterType.Sprite;
            importer.textureCompression = TextureImporterCompression.Uncompressed; // ドット絵で圧縮すると色が崩れる
            importer.filterMode = FilterMode.Point; // ドット絵でポイント以外を使うと超ぼやける
            importer.spriteImportMode = SpriteImportMode.Multiple;
            //importer.spritePixelsPerUnit = 48; // 何ピクセルを1.0とするか?必要ならゲームに合わせてお好みで.
        }
    }

    // code from here: https://forum.unity.com/threads/sprite-editor-automatic-slicing-by-script.320776/
    public void OnPostprocessTexture(Texture2D texture)
    {
        if (IsAssetGridSprite())
        {
            ImportGridSprites(texture);
        }
    }
    private void ImportGridSprites(Texture2D texture)
    {
        TextureImporter importer = assetImporter as TextureImporter;
        if (importer.spriteImportMode != SpriteImportMode.Multiple)
        {
            Debug.LogErrorFormat($"GridスライスするスプライトがMultipleになっていません");
            return;
        }

        var cellSize = new Vector2(48, 48);
        Rect[] rects = UnityEditorInternal.InternalSpriteUtility.GenerateGridSpriteRectangles(texture, Vector2.zero, cellSize, Vector2.zero);
        List<Rect> rectsList = new List<Rect>(rects);

        string filenameNoExtension = System.IO.Path.GetFileNameWithoutExtension(assetPath);
        List<SpriteMetaData> metas = new List<SpriteMetaData>();
        int rectNum = 0;

        foreach (Rect rect in rectsList)
        {
            SpriteMetaData meta = new SpriteMetaData();
            meta.rect = rect;
            meta.alignment = (int)SpriteAlignment.BottomCenter;
            meta.name = filenameNoExtension + "_" + rectNum++;
            metas.Add(meta);
        }

        importer.spritesheet = metas.ToArray();
        AssetDatabase.Refresh();
        Debug.Log($"Generate {metas.Count} sprites from {filenameNoExtension} PostProcess.");
    }
}

いい感じですね! good stuff! f:id:marudice:20210505113122p:plain