自動で9 sliced sprite(9 patch)画像を生成してくれるモジュール作った

  • 26
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

Unity界隈で9sliced spriteと呼ばれている9patchだか9sliceだかの画像を
自動で生成してくれるrubyのモジュールを作りました。
(この記事では9sliced spriteって呼びます。)

9sliced spriteって何?って人はこの辺を参照してください。

リポジトリ

https://github.com/kyubuns/onion_ring

何が出来るの?

こういう画像をつっこむと
before.png

こういう画像が出てきます。
after.png

さらに、[23, 0, 21, 0]というborderの値を得られます。
(left, top, right, bottom)
左から23px, 右から21pxまでを使って、その間を伸ばしてね。っていう指定です。

こういう画像をつっこむと
before.png

こうなります。
after.png

使い方

めんどくさいのでGemとかになってないです。
要望があれば・・・

sample.rb
border = OnionRing::run('before.png', 'after.png')

これだけ。

Unity実用例

ここからUnityの話をします!

sample.rb
# このスクリプトまともに動くか試してないので察してください。
slice_borders = []
slice_borders.push(['after1', OnionRing::run('before1.png', 'after1.png')])
slice_borders.push(['after2', OnionRing::run('before2.png', 'after2.png')])
# さらにここでafter1.png, after2.pngを、TexturePackerでまとめて、hoge_atlas.pngに保存とかすると便利。

slice_borders_text = slice_borders.map{|line| line.flatten.join(',')}.join("\n")
File.write("hoge_atlas_border.txt", slice_borders_text)
cp hoge_atlas_border.txt UnityProject/Assets/Resources/Hoge/

こんなかんじに、小さくした画像 + borderの値をテキストファイルに書いておきます。
そして、UnityのResources以下とか、まあ適当な場所にコピーもします。

AtlasBorderSetter.cs
using UnityEditor;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BorderSetter : AssetPostprocessor
{
    public override int GetPostprocessOrder() { return 200; } // TexturePackerが100

    static void OnPostprocessAllAssets (string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
    {
        foreach (var asset in importedAssets)
        {
            if(!asset.EndsWith("_border.txt")) continue;
            string pathToTexture = asset.Replace("_border.txt", ".png");
            if(File.Exists(pathToTexture)) AssetDatabase.ImportAsset(pathToTexture, ImportAssetOptions.ForceUpdate);
        }
    }

    void OnPreprocessTexture ()
    {
        TextureImporter importer = assetImporter as TextureImporter;

        string pathToData = assetPath.Replace(".png", "_border.txt");
        if (File.Exists(pathToData)) updateSpriteMetaData(importer, pathToData);
    }

    static void updateSpriteMetaData (TextureImporter importer, string pathToData)
    {
        string[] dataFileContent = File.ReadAllLines(pathToData);
        var borders = new Dictionary<string, Vector4>();
        foreach(var line in dataFileContent)
        {
            var elements = line.Split(',');
            var name = elements[0];
            var left = int.Parse(elements[1]);
            var top = int.Parse(elements[2]);
            var right = int.Parse(elements[3]);
            var bottom = int.Parse(elements[4]);
            borders[name] = new Vector4(left, bottom, right, top);
        }

        var metaList = new List<SpriteMetaData> ();
        for(int i = 0; i<importer.spritesheet.Length; ++i)
        {
            var sprite = importer.spritesheet[i];
            sprite.border = borders[sprite.name];
            metaList.Add(sprite);
        }

        importer.spritesheet = metaList.ToArray();
    }
}

後は、↑のスクリプトをUnityのEditor以下に置いておくと、自動的にborderの設定までしてくれます!

リポジトリ

https://github.com/kyubuns/onion_ring

あとがき

自動的に9slice sprite画像を生成してくれるツールを探したんですけど、どうも見当たらなかったので自分で作っちゃいました。
意見・要望などはtwitterや、ここのコメント欄までお気軽にどうぞ!
ruby力低いのでコードへのつっこみもお待ちしてます。

おまけ