Automated Sprite Slicing On Import

I’m trying to finish up an AssetPostProcessor that will automatically slice and create the sprites from a spritesheet based on parameters in the filename.

I have everything working so that the spritesheet does get sliced appropriately and those sprites display correctly in the sprite editor. However, the asset itself does not appear fully imported as it does not have the dropdown arrow with the sprite list in it yet. In order to get that, I have to right click on the asset and select “Reimport”. This results in the expected behavior, but I get some exceptions related to physics outlines…

  1. How can I make sure the texture and sprites are fully processed without having to reimport a second time?
  2. Does anyone know why I might get these exceptions for physics outlines when generating sprite slices from an editor script?

Processor Code

private void OnPostprocessTexture(Texture2D texture)
        {
            AssetDetails details = GetTextureDetails();
           
            if (details.isSpritesheet && details.hasDimens)
            {
                TextureImporter importer = (TextureImporter) assetImporter;

                bool success = GetImageSize(assetPath, out int imageWidth, out int imageHeight);

                if (success)
                {
                    List<SpriteMetaData> metaDatas = new List<SpriteMetaData>();
                    int spriteWidth = imageWidth / details.dimens.cols;
                    int spriteHeight = imageHeight / details.dimens.rows;
                    string filename = Path.GetFileNameWithoutExtension(assetPath);
                    int spriteCount = 0;
                   
                    for (int row = 0; row < details.dimens.rows; ++row)
                    {
                        for (int col = 0; col < details.dimens.cols; ++col)
                        {
                            SpriteMetaData metaData = new SpriteMetaData()
                            {
                                rect = new Rect(col * spriteWidth, row * spriteHeight, spriteWidth, spriteHeight),
                                name = $"{filename}_{spriteCount}"
                            };

                            metaDatas.Add(metaData);

                            ++spriteCount;
                        }
                    }

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

Exceptions

No this is not possible. As the docs say, you should avoid modifying the importer as the changes won’t be applied until a reimport. Unity - Scripting API: AssetPostprocessor.OnPostprocessTexture(Texture2D)

Instead try using this Unity - Scripting API: AssetPostprocessor.OnPreprocessAsset()

Edit:
I was assuming you didn’t want to do a double import but if you just want to avoid having to manually reimport then doing the set dirty, save and reimport is fine :wink:

2 Likes
// do this to your TextureImporter after everything else:
EditorUtility.SetDirty(importer);
importer.SaveAndReimport();
1 Like

Re the physics shape issues…

TextureImporterSettings importerSettings = new TextureImporterSettings();
importer.ReadTextureSettings(importerSettings);
importerSettings.spriteGenerateFallbackPhysicsShape = false;
importer.SetTextureSettings(importerSettings);

I convert all images from an array of paths to a sprite sheet (which Texture2D’s PackTextures definitely simplifies) and that is part of what I do, but I don’t remember if it was necessary - I just got the automation to match up with what I would do by hand before. I can say it is working properly for PNG files without exceptions in 2020.2 on Windows 7 and 10, so if you’re still having problems I’ll see what else might be relevant / share more of how I do that.

@karl_jones - Thanks for pointing out the difference there between the Post and Pre methods. Simply switching the method to a pre-process instead of a post- fixed both issues and helped prevent a second import.

@adamgolden - The set dirty method would have worked as well, I’m sure. However, I wanted to keep import time to a minimum so the optimal way for me was anything that would prevent multiple import passes. As for the physics stuff, I didn’t really follow what you are saying about converting images from an array of paths to a sprite sheet. My images are already sprite sheets when importing.

2 Likes

Glad you got everything working! I create my sprite sheets procedurally, i.e. where I have several folders from which I want all of the images merged into the same sheet. Anyway, congrats! :smile: