Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Atlas for uGUI using Texture Packer

Discussion in 'UGUI & TextMesh Pro' started by lzt120, Aug 22, 2014.

  1. lzt120

    lzt120

    Joined:
    Apr 13, 2010
    Posts:
    93
    As the title. implement the Atlas for uGUI using Texture Packer and see the result in project panel.
     
  2. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    ?
     
  3. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,749
    I think what he means is: Right now, when you're building your GUI, it always uses the raw original images; it's not until you hit play that it switches to the packed atlas.
     
  4. djweinbaum

    djweinbaum

    Joined:
    Nov 3, 2013
    Posts:
    533
    Yeah it doesn't work like Daikon Forge or other sprite packers where it actually creates an atlas object in your project view. You just set the packing tag in the import settings and use the sprites directly. At run-time the draw calls will consolidate. One annoying thing about this is that if you have tons of sprites that you need script to choose from by string (like an inventory list or something), then you need to have something that holds a reference to every single sprite. I made a SpriteHolder component.
     
  5. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    It is possible to enable the sprite packer to get more manual control:
    http://docs.unity3d.com/Manual/SpritePacker.html
     
  6. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,749
    Even with the sprite packer enabled, the GUI doesn't use the packer until you are in play mode. (If you are using a packed sprite that is Compressed, you can plainly see the difference; it's crisp and clear when laying it out and becomes compressed in play mode.) Also, there are bugs using the sprite packer with UI.
     
  7. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    You may e.g. create a scriptable object that holds the references to all your sprites. That scriptable object is updated whenever the atlas is created. It would be necessary to create a custom bundler as shown here, but it certainly would need to modify the scriptable object to update the references:
    http://docs.unity3d.com/Manual/SpriteEditor.html
     
  8. lzt120

    lzt120

    Joined:
    Apr 13, 2010
    Posts:
    93
    What I mean is I want use the TexturePacker to generate the Atlas and then import it to Unity and there is one Atlas just as the NGUI Atlas on the Project Window.
     
  9. lzt120

    lzt120

    Joined:
    Apr 13, 2010
    Posts:
    93
    When I want change the sprite at run-time I can use the name of sprite to change just as doing as NGUI do so.
     
    T2Unity likes this.
  10. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,194
    Why? Just use the in built packer and then change the sprite reference. Unity will to this automatically without needing string name lookups.
     
  11. lzt120

    lzt120

    Joined:
    Apr 13, 2010
    Posts:
    93
    For the convenience to change the sprite in code.I think the TexturePacker(Pro) is the professional even the standard for the Atlas generation.
     
  12. djweinbaum

    djweinbaum

    Joined:
    Nov 3, 2013
    Posts:
    533
    Dude, you can change the sprite in code. Store the reference. If your so hell bent on doing it the way TexturePacker does it, then why don't you use TexturePacker?
     
  13. lzt120

    lzt120

    Joined:
    Apr 13, 2010
    Posts:
    93
    uGUI support the TexturePacker for atlas importing ? TexturePacker will generate one texture and one text file for atlas, how those files can be use for uGUI sprite packer ?
     
  14. lzt120

    lzt120

    Joined:
    Apr 13, 2010
    Posts:
    93
    In MMO Game, the inventory Icon comes from its name in config file,that is why I need use the name for change sprite at code.
     
  15. T2Unity

    T2Unity

    Joined:
    Aug 21, 2014
    Posts:
    26
  16. lzt120

    lzt120

    Joined:
    Apr 13, 2010
    Posts:
    93
    Thanks very much
     
  17. pea

    pea

    Joined:
    Oct 29, 2013
    Posts:
    98
    I've been using the official TexturePacker Importer. It works great with the 4.6 beta except for sliced sprites, which I think the TP Importer doesn't support (yet). So each time I publish my atlas again in TP I have to:
    1. Click into Unity so the TP Importer loads the newly published sheet
    2. Delete the .tpsheet file
    3. Open the Unity Sprite Editor and set up the borders again on my sliced sprites
    It's a little tedious but I assume that TP will eventually update the extension to work with sliced sprites. Also, step 2 is required because otherwise the TP Importer instantly undoes step 3 the moment you hit "Apply" in the Unity Sprite Editor.
     
    rakkarage likes this.
  18. pea

    pea

    Joined:
    Oct 29, 2013
    Posts:
    98
    I found a little shortcut. If you leave the Unity Sprite Editor open while you publish the new TP sheet you can do this:
    1. Click into Unity so the TP Importer loads the newly published sheet
    2. Delete the .tpsheet file
    3. Click into the Sprite Sheet Editor (that you left open) and adjust just one border attribute on one sprite, then hit "Apply"
    It'll re-apply ALL border attributes again, saving you work.
     
    rakkarage and T2Unity like this.
  19. lzt120

    lzt120

    Joined:
    Apr 13, 2010
    Posts:
    93
    How can I store the TextureImporter spritesheet to a list of sprite ?
     
  20. pea

    pea

    Joined:
    Oct 29, 2013
    Posts:
    98
  21. pea

    pea

    Joined:
    Oct 29, 2013
    Posts:
    98
    As in, when the TexturePacker Importer is imported into your Unity project each time a sprite .png file and a .tpsheet file with the same name are published somewhere into your Unity project's asset path it will get automatically converted into a list of Unity sprites.

    E.g. publish mysprites.png and mysprites.tpsheet into MyProject/Assets/stuff/ and then the TexturePacker Importer will automatically do its thing.
     
  22. lzt120

    lzt120

    Joined:
    Apr 13, 2010
    Posts:
    93
    But, how can I change the sprite by Code ?
     
  23. pea

    pea

    Joined:
    Oct 29, 2013
    Posts:
    98
    Sorry, could you explain a little more what you mean by that? Maybe with an example of what you are trying to do?
     
  24. lzt120

    lzt120

    Joined:
    Apr 13, 2010
    Posts:
    93
    How can change the inventory icon at runtime with uGUI ,Atlas made by TexturePacker Importer and the only I know is the name of sprite config with XML file.
     
  25. pea

    pea

    Joined:
    Oct 29, 2013
    Posts:
    98
    The name of the sprite will be the filename of the file you've imported into TexturePacker, without the extension. Example:

    1. my-button.psd goes into TexturePacker.
    2. You export the sprite sheet to Unity.
    3. The sprite will be called "my-button".

    So yeah, filename of original file, minus extension. And spaces get replaced by dashes (-) I think.
     
  26. lzt120

    lzt120

    Joined:
    Apr 13, 2010
    Posts:
    93
    Can you give a little example code for easy reference ?
     
  27. pea

    pea

    Joined:
    Oct 29, 2013
    Posts:
    98
  28. lzt120

    lzt120

    Joined:
    Apr 13, 2010
    Posts:
    93
    Finally I get it out for changing the sprite at run-time, just call
    Code (CSharp):
    1. Resources.Load<Sprite>(string.Format("{0}/{1}",spriteAtlasPath,spriteName));
     
  29. Revolter

    Revolter

    Joined:
    Mar 15, 2014
    Posts:
    216
    Fix for uGUI Sliced Sprites with TexturePacker:

    If you want TexturePacker plugin to save your border settings for a sprite in the atlas, you just have to add a few lines of code to the TexturePackerImporter.cs:

    //Add this before metaData.Add (smd);

    for(int i=0; i<importer.spritesheet.Length; i++)
    {
    if(importer.spritesheet.name == smd.name)
    {
    smd.border = importer.spritesheet.border;
    break;
    }
    }


    That's it, enjoy!
     
    pea likes this.
  30. StrawberryCheeseHat

    StrawberryCheeseHat

    Joined:
    Mar 4, 2015
    Posts:
    2
    Hey lzt120, I followed your advice using the resource load function with passing in the sprite name (since the sprite sheet is directly under the Resouces folder). The code returned null for the sprite.
    I have both spritesheet.tbsheet and spritesheet.png in the resource folder.
    Am I missing some steps? Thank you!
     
  31. StrawberryCheeseHat

    StrawberryCheeseHat

    Joined:
    Mar 4, 2015
    Posts:
    2
    Figured out, need to do Resources.LoadAll. It will return a array of sprites in the spreadsheet.
     
  32. VivienS

    VivienS

    Joined:
    Mar 25, 2010
    Posts:
    24
    The code snipped, for making TexturePacker keep custom border settings upon re-import, is missing array accessors. Here's the complete one that works for me. Thanks a lot!
    Code (CSharp):
    1. //Add this before metaData.Add (smd);
    2. for (int i=0; i<importer.spritesheet.Length; i++)
    3. {
    4.     if(importer.spritesheet[i].name == smd.name)
    5.     {
    6.         smd.border = importer.spritesheet[i].border;
    7.         break;
    8.     }
    9. }