Ruby
Web
Unity

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

More than 3 years have passed since last update.

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力低いのでコードへのつっこみもお待ちしてます。


おまけ