Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by Tomer-Barkan · Apr 09, 2015 at 03:45 PM · editorspriteimporteditor-scripting

Editor script to slice sprites

I'm trying to create an editor tool that will take a bunch of images (each a sprite sheet), slice them up, create animations from them, and create a controller override from a given template with all the right animations in all the right slots.

The idea is to quickly create animations for new characters without having to use the editor's horrible pipeline (slice manually, drag and drop each group, setup the controllers, etc)

Right now I'm stuck in trying to slice the sprite from the editor script. Any ideas how to access the sprite editor or something similar from script?

Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image berg44 · Apr 02, 2016 at 02:58 PM 0
Share

Did you end up completing the whole sequence like you wanted? That sounds exactly like what I am trying to do.

avatar image Liason23 · Sep 28, 2021 at 01:17 PM 0
Share

Can you please tell me how u implement this given solution?

3 Replies

· Add your reply
  • Sort: 
avatar image
7
Best Answer

Answer by Dorque · Apr 18, 2015 at 08:38 PM

I'm in a similar situation where I want to name a large sprite sheet through code. I started with this script here. In order to use these editor scripts you need to put them in a Editor folder. When you restart Unity you should see a Sprites menu at the top with "Rename Sprites" in the dropdown.

I modified it to slice the texture by a 16x16 grid, set the pivot, and then rename the sprites according to their index in the sprite sheet. The top left sprite is (0,0).

I hope this helps.

 using UnityEngine;
 using UnityEditor;
 using System.Collections;
 using System.Collections.Generic;
 
 public class NameSpritesAutomatically : MonoBehaviour {
     
     [MenuItem("Sprites/Rename Sprites")]
     static void SetSpriteNames()
     {        
         Texture2D myTexture = (Texture2D)Resources.LoadAssetAtPath<Texture2D>("Assets/Sprites/MyTexture.png");
 
         string path = AssetDatabase.GetAssetPath(myTexture);
         TextureImporter ti = AssetImporter.GetAtPath(path) as TextureImporter;
         ti.isReadable = true;
 
         List<SpriteMetaData> newData = new List<SpriteMetaData>();
 
         int SliceWidth = 16;
         int SliceHeight = 16; 
 
         for (int i = 0; i < myTexture.width; i += SliceWidth)
         {
             for(int j = myTexture.height; j > 0;  j -= SliceHeight)
             {
                 SpriteMetaData smd = new SpriteMetaData();

                 smd.pivot = new Vector2(0.5f, 0.5f);
                 smd.alignment = 9;
                 smd.name = (myTexture.height - j)/SliceHeight + ", " + i/SliceWidth;
                 smd.rect = new Rect(i, j-SliceHeight, SliceWidth, SliceHeight);
 
                 newData.Add(smd);
             }
         }
 
         ti.spritesheet = newData.ToArray();
         AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
     }
 }

Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Tomer-Barkan · Apr 18, 2015 at 08:51 PM 0
Share

Hmm, I tried setting spritesheet parameter but it had no effect on the imported sprite... I'll try this script and let you know. Thanks for answering.

avatar image Dorque · Apr 19, 2015 at 04:33 PM 0
Share

You know, sometimes I have to run this script twice to see any changes made. I'm not sure why this is.

avatar image Tomer-Barkan · Apr 20, 2015 at 04:52 AM 0
Share

This is very weird... I can swear I tried the exact same thing (setting the spritesheet to something I created) and it did nothing. Now it works perfectly.

Oh well, thanks for the answer.

avatar image Tomer-Barkan · Apr 20, 2015 at 05:23 AM 0
Share

Ok, I figured out why it didn't work when I first tried. Apparently when the sprite is already sliced, the code does nothing... weird unity bug?

Anyway, here is the workaround:

 if (ti.spriteImport$$anonymous$$ode == SpriteImport$$anonymous$$ode.$$anonymous$$ultiple) {
   // Bug? Need to convert to single then back to multiple in order to make changes when it's already sliced
   ti.spriteImport$$anonymous$$ode = SpriteImport$$anonymous$$ode.Single;
   AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
 }

Also, there's a bug with the pivot in the code above. Pivot should be set 0 to 1, so in the example above it should be (0.5,0.5). Also the pivot parameter is useless unless you set the alignment to custom. So add these lines ins$$anonymous$$d of the "smd.pivot=...":

 smd.pivot = new Vector2(0.5f, 0.5f);
 smd.alignment = 9;

Please update your answer with these parts so other people reading this will know.

avatar image gooby429 · Dec 15, 2020 at 05:05 PM 0
Share

Thank you for this, still useful in 2020! I would like to add one correction though... The issue is that if you are using very large textures that go above the max size you have set (for example, max size is 8192, and my texture was 14400). This is unlikely, but on the off chance you cant just change the max size to fit your need, you will need the true size to slice it properly.

Solution: see this function and add it to your code: https://forum.unity.com/threads/getting-original-size-of-texture-asset-in-pixels.165295/

instead of tex.width and tex.height, replace it with what the code gives you to get the true size of the texture.

example:

         int texWidth;
         int texHeight;
         if (GetImageSize(tex, out texWidth, out texHeight)) { }
         else
         {
             Debug.LogError($"Unable to get texture '{tex}' size.");
             return;
         }
Show more comments
avatar image
1

Answer by acfung · May 12, 2018 at 09:15 PM

Try this script

https://gist.github.com/shadesbelow/8a6ddc54db795241f3cff539db6ea487,

This will give you a hotkey to automatically slice sprites just like using Sprite Editor > Slice > Automatic

 using System.Collections.Generic;
 using System.IO;
 using UnityEditor;
 using UnityEditorInternal;
 using UnityEngine;
 
 // This is only useful for spritesheets that need to be automatically sliced (Sprite Editor > Slice > Automatic)
 public class AutoSpriteSlicer
 {
     [MenuItem("Tools/Slice Spritesheets %&s")]
     public static void Slice()
     {
         var textures = Selection.GetFiltered<Texture2D>(SelectionMode.Assets);
 
         foreach (var texture in textures)
         {
             ProcessTexture(texture);
         }
     }
 
     static void ProcessTexture(Texture2D texture)
     {
         string path = AssetDatabase.GetAssetPath(texture);
         var importer = AssetImporter.GetAtPath(path) as TextureImporter;
 
         //importer.isReadable = true;
         importer.textureType = TextureImporterType.Sprite;
         importer.spriteImportMode = SpriteImportMode.Multiple;
         importer.mipmapEnabled = false;
         importer.filterMode = FilterMode.Point;
         importer.spritePivot = Vector2.down;
         importer.textureCompression = TextureImporterCompression.Uncompressed;
 
         var textureSettings = new TextureImporterSettings(); // need this stupid class because spriteExtrude and spriteMeshType aren't exposed on TextureImporter
         importer.ReadTextureSettings(textureSettings);
         textureSettings.spriteMeshType = SpriteMeshType.Tight;
         textureSettings.spriteExtrude = 0;
 
         importer.SetTextureSettings(textureSettings);
 
         int minimumSpriteSize = 16;
         int extrudeSize = 0;
 
         Rect[] rects = InternalSpriteUtility.GenerateAutomaticSpriteRectangles(texture, minimumSpriteSize, extrudeSize);
         var rectsList = new List<Rect>(rects);
         rectsList = SortRects(rectsList, texture.width);
 
         string filenameNoExtension = Path.GetFileNameWithoutExtension(path);
         var metas = new List<SpriteMetaData>();
         int rectNum = 0;
 
         foreach (Rect rect in rectsList)
         {
             var meta = new SpriteMetaData();
             meta.pivot = Vector2.down; 
             meta.alignment = (int)SpriteAlignment.BottomCenter;
             meta.rect = rect;
             meta.name = filenameNoExtension + "_" + rectNum++;
             metas.Add(meta);
         }
 
         importer.spritesheet = metas.ToArray();
 
         AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
     }
 
     static List<Rect> SortRects(List<Rect> rects, float textureWidth)
     {
         List<Rect> list = new List<Rect>();
         while (rects.Count > 0)
         {
             Rect rect = rects[rects.Count - 1];
             Rect sweepRect = new Rect(0f, rect.yMin, textureWidth, rect.height);
             List<Rect> list2 = RectSweep(rects, sweepRect);
             if (list2.Count <= 0)
             {
                 list.AddRange(rects);
                 break;
             }
             list.AddRange(list2);
         }
         return list;
     }
 
     static List<Rect> RectSweep(List<Rect> rects, Rect sweepRect)
     {
         List<Rect> result;
         if (rects == null || rects.Count == 0)
         {
             result = new List<Rect>();
         }
         else
         {
             List<Rect> list = new List<Rect>();
             foreach (Rect current in rects)
             {
                 if (current.Overlaps(sweepRect))
                 {
                     list.Add(current);
                 }
             }
             foreach (Rect current2 in list)
             {
                 rects.Remove(current2);
             }
             list.Sort((a, b) => a.x.CompareTo(b.x));
             result = list;
         }
         return result;
     }
 }

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by dmitry_veshchikov · Jan 27 at 11:12 PM

Add this line:

 ti.spriteImportMode = SpriteImportMode.Multiple;

Before:

 AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);


It will set the image asset automatically to be multiple sprites, saving you time setting it manually from "Single" to "Multiple" in the editor, and preventing a headache where you don't know why the script isn't working.,Add this line:

ti.spriteImportMode = SpriteImportMode.Multiple;

Before:

AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);

It will set the image asset automatically to be multiple sprites, saving you time setting it manually to multiple in the editor, and preventing a headache where you don't know why the script isn't working.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

24 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Editor class "Texture Importer" question (applying settings to multiple texture assets). 2 Answers

Serialize class that derives from abstract class 2 Answers

How to Rename Sprite Slices in Script Without Breaking References 3 Answers

How to some action when files import end? 0 Answers

Editor Script Selection thinks Sprites are Texture2Ds. 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges