[Unity] 1枚の画像を用途毎にサイズを指定して分割したい(SpriteEditor/エディタ拡張)

 - 1枚の立ち絵から全身/バストアップ/サムネイル...etc を(Unity内で)切り分けたい

![unitychan.png](https://qiita-image-store.s3.amazonaws.com/0/102664/1eefef58-1ecf-22af-7971-44097ecdff37.png)

## SpriteEditorを使用して画像を分割する
- https://docs.unity3d.com/ja/current/Manual/SpriteEditor.html
- Projectビューより任意の画像ファイルを選択する
- **TextureMode** : **Sprite (2D & UI)** に指定する
- **SpriteMode** : **Multiple** に指定する
- **[SpriteEditor]** を開く

![spriteinspector.png](https://qiita-image-store.s3.amazonaws.com/0/102664/31492ce3-7029-f6ee-a63d-65c6573c3b15.png)

### SpriteEditor
- ドラッグで任意の矩形を選択する事で、その矩形の箇所をSpriteとして取り扱う事が出来る
- ドラッグで作成した矩形は `(Cmd|Ctrl) + delete` で消す事が出来る
- ドラッグで作成した矩形をクリックすると、そのSpriteの情報が表示される
  - Nameの指定やサイズの微調整が可能
  - 任意のNameを指定する事でScriptから動的に個別のSpriteを呼び出す事が可能に
  - (ただし、Resources/AssetBundleを利用した時のみ)
  - [ResourcesからスライスしたSpriteを取得する3つの方法 - テラシュールブログ](http://tsubakit1.hateblo.jp/entry/20131222/1387654182)
  - [【Unity】AssetBundleからMultiple Spriteに含まれるスプライトを取得する方法とその周辺 - テラシュールブログ](http://tsubakit1.hateblo.jp/entry/2015/11/14/000000)
- 最終的に変更をApplyしないと反映されないので注意
  - 変更を取り消したかったら Revert すればよい

![spriteeditor.gif](https://qiita-image-store.s3.amazonaws.com/0/102664/6c69fb60-bd6e-ee26-ed15-db149020c1a7.gif)

### SpriteEditor: Slice
- また1枚のSpriteに複数の要素が含まれている場合、右上の **[Slice]** で自動的に分割可能
- このとき、既に画像を分割していた場合、解除して新規に分割が行われるので注意
- Type: **Automatic** は自動的にSpriteの領域を識別して分割する君
- Type: **Grid By Cell Size** は1つのSpriteのサイズを指定し、分割する君
- Type: **Grid By Cell Count** はSpriteを何等分するか指定し、分割する君
  - Grid By Cell (Size|Count) は要素が含まれない領域に関してはSpriteが作成されない

![autoslice.gif](https://qiita-image-store.s3.amazonaws.com/0/102664/3ddcdd4e-ded9-3bbb-e935-03892a6e625e.gif)

## Editor拡張で指定した画像を指定したサイズに分割する
- ドラッグで範囲指定する場合、画像毎に大きさがブレやすい
- かといって、SpriteEditor上で個別に画像の大きさを数値で入力するのは面倒
- 「一括」で「決められたサイズ」に画像を分割したい

### 参考
- なお以下のコードは9割こちらの記事を参考にしています！
- [縦横の分割数を指定し一枚の画像をMultiple Spriteに分割するEditor拡張コード](http://qiita.com/RyotaMurohoshi/items/b01e3cdb91fea96f4574)

### コード

```csharp
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
using System.Linq;

public static class SpriteSeparater
{
    // 名称 / サイズの指定箇所
    // 全ての画像で各要素の位置があらかた決まっているのであればX/Y座標も入れておく
    // 任意のConfigファイルに移行して参照するのが良さそう
    public static Dictionary<string, Rect> Name2RectMap = new Dictionary<string, Rect>()
    {
        { "thumbnail", new Rect(0, 0, 500, 500) },
        { "face",      new Rect(0, 0, 800, 800) },
        { "bustup",    new Rect(0, 0, 1500, 1600) }
    };

    // 上部メニュー "Assets/Sprite/Separate" より呼び出せる様にする
    [MenuItem("Assets/Sprite/Separate")]
    public static void SeparateSprite()
    {
        // Selection.objects で現在Projectビューで選択しているファイル群が指定出来る
        IEnumerable<Texture> targets = Selection.objects.OfType<Texture>();
        if (!targets.Any())
        {
            Debug.LogWarning ("Please selecting textures.");
            return;
        }

        foreach (Texture target in targets)
        {
            Separate(AssetDatabase.GetAssetPath(target));
        }
    }

    public static void Separate(string texturePath)
    {
        TextureImporter importer = TextureImporter.GetAtPath(texturePath) as TextureImporter;

        // Update textureType
        importer.textureType = TextureImporterType.Sprite;
        importer.spriteImportMode = SpriteImportMode.Multiple;
        importer.filterMode = FilterMode.Point;
        EditorUtility.SetDirty(importer);
        AssetDatabase.ImportAsset(texturePath, ImportAssetOptions.ForceUpdate);

        // spriteImportMode separate
        SpriteMetaData[] sprites = Name2RectMap.Keys.Select(
            name => new SpriteMetaData
            {
                name = name,
                rect = Name2RectMap[name]
            }
        ).ToArray();

        importer.spritesheet = sprites;
        EditorUtility.SetDirty(importer);
        AssetDatabase.ImportAsset(texturePath, ImportAssetOptions.ForceUpdate);
    }
}
```

### 使い方
- 1枚、または複数の画像を選択し、上部メニュー "Assets/Sprite/Separate" を選択する
- 指定したサイズでSpriteが分割されているので、ドラッグして任意の位置に合わせる

![separate.gif](https://qiita-image-store.s3.amazonaws.com/0/102664/0602fdab-5479-aed3-c452-7852d499b892.gif)
(実行後、処理終了まで多少時間掛かるので注意)

---

<div><img src="http://unity-chan.com/images/imageLicenseLogo.png" alt="ユニティちゃんライセンス"><p>この作品は<a href="http://unity-chan.com/contents/license_jp/" target="_blank">ユニティちゃんライセンス条項</a>の元に提供されています</p></div>