Update and Slice all your Sprite Assets at once with InternalSpriteUtility.GenerateGridSpriteRectangles
and AssetDatabase.ImportAsset
in Unity3D!
🐍👑🌍
Intro
Prerequirements:
- Sprites are located in
Assets/Resources/myfolder
- Create a Script in
Assets/Scripts/UnityTools.cs
Docs:
- Unity Asset & Resource Learn Tutorial https://learn.unity.com/tutorial/assets-resources-and-assetbundles/
- TextureImporter https://docs.unity3d.com/ScriptReference/TextureImporter.html
- SpriteMetaData https://docs.unity3d.com/ScriptReference/SpriteMetaData.html
- Resources.LoadAll https://docs.unity3d.com/ScriptReference/Resources.LoadAll.html
Slice by Cell Size (with
empty rects)
Divide Sprites by a given Width+Height:
- name_0x0
- name_0x1
- name_0x2
- […]
- name_1x0
- name_1x1
- […]
Script may be run via Tools
> FCO
> Compute Sprites
.
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using UnityEditorInternal; // for InternalSpriteUtility
using System.Linq; // for Cast()
public class UnityTools : MonoBehaviour{
[MenuItem("Tools/FCO/Compute sprites")]
static void ComputeSprites(){
Debug.Log("ComputeSprites: start");
int sliceWidth = 64;
int sliceHeight = 64;
string folder = "myfolder";
Texture2D[] textures = Resources.LoadAll(folder, typeof(Texture2D)).Cast<Texture2D>().ToArray();
Debug.Log("ComputeSprites: textures.Length: " + textures.Length);
List<string> allowlist = new List<string>{
"character15",
// "character28", // will not be updated by this script
"character41",
};
foreach (Texture2D texture in textures){
Texture2D texture = resource as Texture2D;
if(!allowlist.Contains(texture.name)){
continue;
}
Debug.Log("ComputeSprites:name: "+texture.name);
string path = AssetDatabase.GetAssetPath(texture);
TextureImporter ti = AssetImporter.GetAtPath(path) as TextureImporter;
ti.isReadable = true;
// constants
ti.textureType = TextureImporterType.Sprite;
ti.spriteImportMode = SpriteImportMode.Multiple;
ti.spritePixelsPerUnit = 73;
ti.filterMode = FilterMode.Point;
ti.textureCompression = TextureImporterCompression.Uncompressed;
List<SpriteMetaData> newData = new List<SpriteMetaData>();
// https://answers.unity.com/questions/1113025/batch-operation-to-slice-sprites-in-editor.html
for (int i = 0; i < texture.width; i += sliceWidth){
for (int j = texture.height; j > 0; j -= sliceHeight)
{
SpriteMetaData smd = new SpriteMetaData();
smd.pivot = new Vector2(0.5f, 0.5f);
smd.alignment = SpriteAlignment.Center;
int rowNum = (texture.height - j) / sliceHeight;
int colNum = i / sliceWidth;
smd.name = texture.name+"_"+rowNum+"x"+colNum; // "name_1x7" for 2nd row & 8th column
smd.rect = new Rect(i, j - sliceHeight, sliceWidth, sliceHeight);
newData.Add(smd);
}
}
ti.spritesheet = newData.ToArray();
AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate); // this takes time, approx. 3s per Asset
Debug.Log("ComputeSprites: resource ok");
}
Debug.Log("ComputeSprites: done");
}
}
Slice by Cell Size (without
empty rects)
Divide Sprites by a given Width+Height, ignoring empty Rectangles:
- name_0
- name_1
- name_2
- […]
Edit the for
loop as follow:
List<SpriteMetaData> newData = new List<SpriteMetaData>();
// https://forum.unity.com/threads/custom-texture-importer-for-automatically-generating-sprites-not-working.1022650/
Rect[] rects = InternalSpriteUtility.GenerateGridSpriteRectangles(
texture, Vector2.zero, new Vector2(sliceWidth,sliceHeight), Vector2.zero);
for (int i = 0; i < rects.Length; i++){
SpriteMetaData smd = new SpriteMetaData();
smd.rect = rects[i];
smd.pivot = new Vector2(0.5f, 0.5f);
smd.alignment = (int)SpriteAlignment.Center;
smd.name = texture.name+"_"+i; // name_41
newData.Add(smd);
}
Finale Sprites structure: