Search Unity

[Free Asset] Simple Sprite Packer

Discussion in 'UGUI & TextMesh Pro' started by ChoMPi, Oct 8, 2014.

  1. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    Hey guys,

    Since the integrated sprite packer is for the pro version only i have decided to write my own little sprite packer to ease my workflow and so i decided to share it with the community. It's really simple and easy to use.

    I haven't yet tested it fully but i hope you guys post some feedback and maybe some improvement suggestions.

    Open in the Asset Store



    It's features include:
    • MaxRects packing method.
    • Unity packing method.
    • Separate Drag and Drop window.
    • Texture resource packing.
    • Sprite resource packing.
    • Sprite data transfer.
    • Action queue.
    • Source sprite reference replacing tool.
    Changelog:
    • Version 1.7
      • Source sprite reference replacing tool will now also set the values of structs.
      • Source sprite reference replacing tool will now target only prefabs if the target is Project.
    • Version 1.6
      • Greatly improved source sprite reference replacing speed.
    • Version 1.5
      • Extended the source sprite reference replacing tool.
    • Version 1.4
      • Added source sprite reference replacing tool.
    • Version 1.3
      • Simple Sprite Packer no longer prevents building.
    • Version 1.2
      • Improved MaxRects packing performance be pre-estimating the texture size (Provided by Vrvyus).
    • Version 1.1
      • Fixed packing issue when the source is Sprite of type Multiple.
      • Inspector will no Repaint when settings are changed in the SPSettings window.
     
    Last edited: Oct 22, 2014
    Caio_Lib, rakkarage and mgear like this.
  2. Vrvyus

    Vrvyus

    Joined:
    May 23, 2014
    Posts:
    4
    This is pure awesomeness :)

    my feedback:
    • multiselect of sprites would be nice,
    • I sometimes get an error when adding several sprites:
    Code (CSharp):
    1. Array size must be at least width*height
    2. UnityEngine.Texture2D:SetPixels(Color[])
    3. SimpleSpritePacker.SPInstance:RebuildAtlas() (at Assets/Simple Sprite Packer/SPInstance.cs:459)
    4. SimpleSpritePackerEditor.SPInstanceEditor:DrawActionButtons() (at Assets/Simple Sprite Packer/Editor/SPInstanceEditor.cs:90)
    5. SimpleSpritePackerEditor.SPInstanceEditor:OnInspectorGUI() (at Assets/Simple Sprite Packer/Editor/SPInstanceEditor.cs:58)
    6. UnityEditor.DockArea:OnGUI()
    thanks



    Edit:
    I just modified SPInstance.cs:458 to
    Code (CSharp):
    1. Color[] pixels = sourceSprite.texture.GetPixels( 0, 0, texture.width, texture.height );
    so it copies non-trimmed sprite.
     
    Last edited: Oct 8, 2014
    ChoMPi likes this.
  3. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    If you are importing a sprite that is part of sprite collection (Atlas) you'll copy the whole texture and not just the sprite you are importing.
     
    Last edited: Oct 8, 2014
  4. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    I think i tracked down the problem, you can re-download the package and test it out.

    After reading the documentation of SetPixels i noticed the texture we are setting the pixels must be ARGB32 format and in the script i did not specified the TextureFormat... So i think that was the problem.

    Edit: When i think of it, it might be the GetPixels that's failing and not the SetPixels...
    Edit again: Might be cause i used Sprite.rect for the new texture size and Sprite.textureRect for the pixel extraction...
    Edit again: It's been fixed, Sprite.textureRect was the problem and the fix was to use Sprite.rect instead.
     
    Last edited: Oct 8, 2014
    Vrvyus likes this.
  5. Mikeysee

    Mikeysee

    Joined:
    Oct 14, 2013
    Posts:
    155
    Wow this is great work ChoMPi! This deserves more eyeballs :)
     
    ChoMPi likes this.
  6. Vrvyus

    Vrvyus

    Joined:
    May 23, 2014
    Posts:
    4
    It works great now :)
    I added atlas size estimation in UITexturePacker.cs. It makes it a tiny bit faster for larger atlases.

    Code (CSharp):
    1.     public static Rect[] PackTextures (Texture2D texture, Texture2D[] textures, int padding, int maxSize)
    2.     {
    3.         int area = 0;
    4.         for ( int i = 0; i < textures.Length; i++ )
    5.         {
    6.             Texture2D tex = textures[i];
    7.             area += tex.width * tex.height;
    8.         }
    9.         int startW = 4;
    10.         int startH = 4;
    11.         while ( startW * startH < area )
    12.         {
    13.             if ( startW <= startH ) startW *= 2;
    14.             else startH *= 2;
    15.         }
    16.         if ( startW > maxSize || startH > maxSize ) return null;
    17.  
    18.         return PackTextures( texture, textures, startW, startH, padding, maxSize );
    19.     }
     
    Last edited: Oct 9, 2014
    ChoMPi likes this.
  7. Vrvyus

    Vrvyus

    Joined:
    May 23, 2014
    Posts:
    4
    Another feature that would be nice. Option for RGB (opaque) texure atlas. :)

    Edit: nevermind, you can just change compression of the atlas :)
     
  8. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    Do you mean applying a background to each sprite in the atlas ?
     
  9. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    I just realized that the Sprite Packer is preventing projects from building, gonna have to move some thing around to fix it...
     
  10. Vrvyus

    Vrvyus

    Joined:
    May 23, 2014
    Posts:
    4
    If you move all the files in Editor subfolder, it works.
     
  11. vptb

    vptb

    Joined:
    Jan 15, 2014
    Posts:
    28
    My Unity is crashing every time I try to create a Sprite Packer, I'm using it on Mac btw.

    Just a question though, let's say I have a texture with 4 sprites, when I create the atlas using this tool, will the Sprite Renderers reference the sprites on the new atlas? without me having to do it manually?
     
  12. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    A. I dont have access to a Mac, maybe you could post the Editor.log from the crash?
    B. No, currently it does not replace references... But i could script that real easy : ]
     
  13. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,413
    Tried on imac, works for me.. (with older unity4.5.0)
     
  14. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    Just uploaded v1.4 with a Source Sprite Reference Replacing Tool : ]
     
  15. vptb

    vptb

    Joined:
    Jan 15, 2014
    Posts:
    28
    I tested it on another machine and it worked perfectly. That replacing tool is amazing, but is it possible to replace the sprites in all scenes? or let the user choose the scenes? Because atm is either the current scene or the project, and in a project like mine which has a lot of scenes (100+), I have to go through all of them and use the replace tool.

    What an awesome tool you just created!
     
    ChoMPi likes this.
  16. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    Well, the contents of the scene are not available till the scene is loaded, so maybe if i made the tool load each scene and replace the sprites it could work... I'll give it a try today. : ]
     
  17. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    It's done, you can re-download the sprite packer package and test it out.
    It takes the enabled scenes in the build settings.
     
    Last edited: Oct 13, 2014
  18. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
  19. Demonith88

    Demonith88

    Joined:
    Jun 30, 2014
    Posts:
    216
    I get error

    Assets/Simple Sprite Packer/Scripts/Editor/SPAtlasBuilder.cs(195,63): error CS1501: No overload for method `PackTextures' takes `4' arguments
     
  20. tnbao91

    tnbao91

    Joined:
    Sep 5, 2013
    Posts:
    46
    I got it too, please fix :)
     
  21. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    Since unity's sprite packer in now available in the free version there's no point in using this asset anymore...
     
  22. tnbao91

    tnbao91

    Joined:
    Sep 5, 2013
    Posts:
    46
    Do you know how to access sprite in atlas make by Sprite Packer ? I need to change sprite on run time but I dont know how to do this ? :)
     
  23. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    You cant do that, resources are not meant to be modified at runtime... What exactly are you trying to achieve anyway ?
     
  24. tnbao91

    tnbao91

    Joined:
    Sep 5, 2013
    Posts:
    46
    I have 10 texture and they are packed to one atlas (use Sprite Packer) because I wanna reduce drawcall. But when I wanna change sprite at runtime, I don't know how to find atlas and sprite to change. No method no api to find texture atlas.
     
  25. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    Why would you wanna change a sprite at run time ?
     
  26. tnbao91

    tnbao91

    Joined:
    Sep 5, 2013
    Posts:
    46
    My game is about bubbles. It's have a lot of kind bubble, I packed them to 1 atlas, when player play and touch bubble change sprite.
     
  27. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    You do not need to modify the atlas for that, just set override sprite on the image component...
     
  28. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    Take a look at this tutorial
     
  29. tnbao91

    tnbao91

    Joined:
    Sep 5, 2013
    Posts:
    46
    It's about drawcall. If I just override separation sprite, drawcall not reduce. 5 bubbles 5 sprite will make 5 drawcall but when packed sprites to 1 atlas, I can have 5 bubble with 5 sprite (in 1 atlas) and only 1 drawcall. In game, when I wanna change sprite any bubble, drawcall do not increase.

    Sorry for my bad English.
     
  30. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    Dude the two sprites are part of the same atlas which makes it 1 draw call... it doesnt matter how you use them.
     
  31. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    5 bubbles, same sprite, 1 draw call.
     
  32. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    Maybe you need to understand how the unity sprite packer works... take a look at this tutorial

     
  33. tnbao91

    tnbao91

    Joined:
    Sep 5, 2013
    Posts:
    46
    5 bubbles, 5 sprite same packing tag, 1 drawcall. I did it same that tutorial you show. 5 sprites bubble same packing tag "Bubble" and when I use any sprite in this atlas "Bubble", just make 1 drawcall. Work fine so far but only one issue, I can't change sprite in this atlas at runtime, I don't know how to do that because I can't access to atlas, I don't see any altas file generate by Sprite Packer to load.
     
  34. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    You don't need to modify resources to achieve highlight effect, just set the override sprite to another sprite of the same atlas...
     
  35. tnbao91

    tnbao91

    Joined:
    Sep 5, 2013
    Posts:
    46
    I think you miss understand. Let's create 5 sprite renderer with 5 difference sprite and tell me how many drawcall you have.
     
  36. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    The same draw calls as if it's the same sprite 5 times...
     
  37. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
  38. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    Make sure you have set the sprite packer to pack in edit mode and you hit the play button when you test.
     
  39. tnbao91

    tnbao91

    Joined:
    Sep 5, 2013
    Posts:
    46
    Yes, so how to change sprite by code ? I can't access to sprite atlas make by Sprite Packer
     
  40. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    The easiest way would be to save references to the sprites on a MonoBehaviour script...
     
  41. tnbao91

    tnbao91

    Joined:
    Sep 5, 2013
    Posts:
    46
    I dont wanna save because maybe have alot of sprite (100-200 sprites) and when I modify atlas, I must change sprite on MonoBehaviour again and again. If I can access the atlas by script, I just remember the name of sprite and I can get it from a method with name param, so easy. Your solution seem not to be the right way.