[Solved] Slicing a Sprite through script on Importing

Hey all,

I’ve written some script that slices a sprite into equal regions like a grid according to a region Width and Height property. When I updated Unity to 2019.2, this script stopped working properly. This script is accessed in an editor window I built that allows me to choose a png file through a file browser and import it.

If I import an image that isn’t a Power of Two, the image is resized to the nearest Power of Two automatically, and then the slicing gets messed up. For example, If I import an image thats 160x48 and attempt to slice it into chunks of 16x16, I expect 30 slices (10x3). However, the image actually comes in at 128x64 and that results in 24 slices (8x4).

Here’s the script:

public static void SliceSprite(string texturePath, int sizeX, int sizeY) {
    TextureImporter textureImporter = AssetImporter.GetAtPath(texturePath) as TextureImporter;
  
    if (textureImporter == null) {
        return;
    }

    textureImporter.textureType = TextureImporterType.Sprite;
    textureImporter.spriteImportMode = SpriteImportMode.Multiple;
    textureImporter.spritePixelsPerUnit = GameProperties.PixelsPerUnit;
    textureImporter.filterMode = FilterMode.Point;
    textureImporter.wrapMode = TextureWrapMode.Clamp;
    textureImporter.maxTextureSize = 2048;
    textureImporter.textureCompression = TextureImporterCompression.Uncompressed;
    textureImporter.crunchedCompression = false;
    textureImporter.compressionQuality = 100;
    textureImporter.isReadable = true;
    textureImporter.textureShape = TextureImporterShape.Texture2D;
    textureImporter.npotScale = TextureImporterNPOTScale.None;

    AssetDatabase.ImportAsset(texturePath, ImportAssetOptions.ForceUpdate);
  
    Texture2D sourceTexture = (Texture2D) AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D));
  
    Debug.Log(sourceTexture.width);
    Debug.Log(sourceTexture.height);

    List<SpriteMetaData> spriteMetaDatas = new List<SpriteMetaData>();
    int frameNumber = 0;
    for (int j = sourceTexture.height; j > 0; j -= sizeY) {
        for (int i = 0; i < sourceTexture.width; i += sizeX) {
            SpriteMetaData spriteMetaData = new SpriteMetaData {
                name = sourceTexture.name + "_" + frameNumber,
                rect = new Rect(i, j - sizeY, sizeX, sizeY),
                alignment = 0,
                pivot = new Vector2(0f, 0f)
            };

            spriteMetaDatas.Add(spriteMetaData);
            frameNumber++;
        }
    }
  
    Debug.Log(spriteMetaDatas.Count);
    textureImporter.spritesheet = spriteMetaDatas.ToArray();
    AssetDatabase.ImportAsset(texturePath, ImportAssetOptions.ForceUpdate);
}

This code will Log the correct width and height, but won’t slice the image. The second Log of spriteMetaDatas.Count will report the correct number of slices.

If I remove Line 21, the Logs will report the wrong image size (resized to the nearest Power of Two), and the sprite will be sliced but incorrectly.

How do I fix it so that I can slice with the correct Dimensions?

2 Likes

Thanks to some help on the GDL Discord Unity-Dev channel, I got the solution.

I added:

EditorUtility.SetDirty(textureImporter);

After Line 21 where the Asset was imported with the first set of settings

5 Likes

Work for me too!!! Thanks!