Author Topic: Font Maker and HD Atlases  (Read 9045 times)

electrodruid

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 48
    • View Profile
Font Maker and HD Atlases
« on: March 14, 2013, 06:12:14 AM »
Hi,

So I'm switching my UI over to use a reference atlas so I can do the SD/HD stuff. As I understand it, the SD and HD atlases should have the same layout, and the sprites on them should have identical names. The tools the artist uses to generate the textures ends up spitting them all out into the same folder, with the HD textures having "@2x" stuck on the end, so it's a bit of work to seperate them out into seperate SD and HD folders and then renaming them all back to the original names, but I realise that's not NGUI's fault and that it's probably not trivial to support atlas sprites having different names on different atlases. But when it comes to creating the fonts, it all goes a bit weird.

For SD, I drag the SD version of MyAwesomeFont.png and MyAwesomeFont.txt into the Font Maker tool, and it dumps a MyAwesomeFont.prefab into the root of the Assets folder. I go and find it, and manually move it to where I actually wanted to create it (say, in Assets/Prefabs/UI/SD), because the Font Maker and Atlas Maker tools don't let you specify where you want to create stuff. Then I go to do the same for the HD version, but because there is now already a font called MyAwesomeFont, the Font Maker doesn't want to create a new version for me, it wants to replace the existing version. So as far as I can see, there's no way to have two versions of a font with the same name, because the Font Maker doesn't allow it. Do I have to create them with different names, move them into the correct folders and rename them by hand? Seems like a bit of an icky workflow. Or am I missing something?

electrodruid

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 48
    • View Profile
Re: Font Maker and HD Atlases
« Reply #1 on: March 14, 2013, 06:26:35 AM »
Urgh, and now another problem - even though the artist I'm working with generated two sets of fonts for me (e.g. a SD version at 30pts, and a HD version of the same font at 60pts), it looks like the exporter laid the fonts out differently, which means that the HD version of some of the font textures aren't exactly double the width and height of the SD versions, which means that the atlases end up with different layouts even though all the elements on them are named the same.

Is that a problem? Is having an identical layout on both atlases an absolute requirement, or will widgets be able to find their textures properly despite the different layouts?

Nicki

  • Global Moderator
  • Hero Member
  • *****
  • Thank You
  • -Given: 33
  • -Receive: 141
  • Posts: 1,768
    • View Profile
Re: Font Maker and HD Atlases
« Reply #2 on: March 14, 2013, 07:21:46 AM »
That's not a problem.

electrodruid

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 48
    • View Profile
Re: Font Maker and HD Atlases
« Reply #3 on: March 19, 2013, 06:26:54 AM »
Bumping this because I didn't get any kind of response about the Font Maker not seeming to support saving to different folders or having multiple fonts with the same name. But also because I seem to have hit a big problem which wasn't made obvious in the tutorial video :(

I have several large complex NGUI scenes made mostly from prefabs, and I went through and changed all of the elements over to point to a reference atlas that I could use to do the SD/HD switch. But because I had several scenes, and the scenes were made from prefabs, I made the reference atlas be a prefab as well, so that everything could reference it. Switching over all the widgets to use this new atlas and applying the changes to my prefabs took me about a day's worth of work. Now that I've come to write the script to do the atlas swap, I realise that I can't change prefabs at runtime (only instances of them), so my atlas swap doesn't work. Help! Is my only option to spend another day adding an instance of the reference atlas to every single prefab, and changing all of the widgets in all of the prefabs to point at an instance? Is there some kind of editor script I could use to automate the process and save myself a day of tedious clicking? Or should I write a script that just does it at runtime - finds every UISprite and UIFont in the scene and changes their references depending on device resolution, basically ignoring the reference atlas altogether?
« Last Edit: March 19, 2013, 06:35:23 AM by electrodruid »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Font Maker and HD Atlases
« Reply #4 on: March 19, 2013, 07:25:00 AM »
Once you have an atlas, it's easier to create a copy of it, then just change the atlas you already have to reference to the copy. This way all your widgets referencing the original atlas don't need to change at all.

There are many atlas changing scripts on this forum. http://www.tasharen.com/forum/index.php?topic=832 for example.

electrodruid

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 48
    • View Profile
Re: Font Maker and HD Atlases
« Reply #5 on: March 19, 2013, 09:12:14 AM »
Once you have an atlas, it's easier to create a copy of it, then just change the atlas you already have to reference to the copy. This way all your widgets referencing the original atlas don't need to change at all.

I don't really understand what you mean by this. Anyway, I bit the bullet and wrote a script that will automatically switch over every sprite and label to reference the same atlas in the scene (i.e. an instance of the reference atlas prefab). You have to manually make sure that your scene contains exactly one instance of the UIAtlas you want, and you have to manually make sure that everything in the scene hierarchy is activated, otherwise the script won't find it (stupid Unity find methods, grr...  >:(). But it still saves a LOT of time compared to doing it manually. I thought other people might find it useful:

  1. [MenuItem ("Custom/Fix Up Atlas References")]
  2.     static void FixUpAtlasRefs()
  3.     {
  4.                 UIAtlas[] atlases = FindObjectsOfType(typeof(UIAtlas)) as UIAtlas[];
  5.                
  6.                 // This will only work if there is but one solitary atlas in the scene.
  7.                 // Othewise we won't know which one to pick as the replacement.
  8.                 if(atlases.Length == 1)
  9.                 {
  10.                         UIAtlas newAtlas = atlases[0];
  11.                        
  12.                         // Won't work with deactivated objects, so you'll need to manually activate everything first.
  13.                         // Thanks, Unity... *sigh*
  14.                         UISprite[] sprites = FindObjectsOfType(typeof(UISprite)) as UISprite[];
  15.                        
  16.                         if(sprites != null)
  17.                         {
  18.                                 foreach(UISprite sprite in sprites)
  19.                                 {
  20.                                         sprite.atlas = newAtlas;
  21.                                 }
  22.                         }
  23.                        
  24.                         UILabel[] labels = FindObjectsOfType(typeof(UILabel)) as UILabel[];
  25.  
  26.                 if(labels != null)
  27.                         {
  28.                                 foreach(UILabel label in labels)
  29.                                 {
  30.                                         label.font.atlas = newAtlas;
  31.                                 }
  32.                         }
  33.                        
  34.                 Debug.Log("Fixed up " + sprites.Length + " sprites and " + labels.Length + "labels");
  35.                 }
  36.                 else
  37.                 {
  38.                         Debug.Log("Found " + atlases.Length + " UIAtlases in the scene. There should be exactly 1 UIAtlas in the scene.");
  39.                 }
  40.     }

I'm guessing from the lack of response to my original question about Font Maker that the workflow is indeed as I suspected/feared - make SD Font, manually move it to where you want it, make HD Font with a different name so that Font Maker will let you save it, manually move that to where you want it, and manually rename it back to the same name as SD Font. Repeat the process every time you need to add a new font or edit existing ones.

Nicki

  • Global Moderator
  • Hero Member
  • *****
  • Thank You
  • -Given: 33
  • -Receive: 141
  • Posts: 1,768
    • View Profile
Re: Font Maker and HD Atlases
« Reply #6 on: March 19, 2013, 11:46:08 AM »
Why would you name two different fonts the same?

We always do something like this: Arial size 20 for low res, 40 for high res

I call them
Arial20
Arial40

and load them by name from resources.



So, what ArenMook meant is that if you are using the same Atlas prefab for all the widgets in all of your scenes, you can do the following:

Make a copy of your original atlas.
Change OriginalAtlas to be a reference atlas.
Set CopyAtlas to be that reference.

Switch OriginalAtlas' reference when needed (to HD or SD or ultra HD).

That way all your already made widgets will still point to OriginalAtlas, but it is now a reference atlas and does all the things you want it to do.

electrodruid

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 48
    • View Profile
Re: Font Maker and HD Atlases
« Reply #7 on: March 19, 2013, 12:46:22 PM »
Ah, that makes sense... Would have saved me some work if I'd've thought about it! Oh well :)

I might have missed something else, but I didn't see how the fonts (or any of the other textures in the atlas) could have different names. If I've got labels that use an Arial20 font when the reference atlas points to my SD atlas, I don't see how NGUI could know to swap them over to use Arial40 when I switch the reference over to the HD atlas. Aren't fonts and textures identified by name within the atlases? Which would mean that the names would have to be the same on both atlases.

Nicki

  • Global Moderator
  • Hero Member
  • *****
  • Thank You
  • -Given: 33
  • -Receive: 141
  • Posts: 1,768
    • View Profile
Re: Font Maker and HD Atlases
« Reply #8 on: March 19, 2013, 04:00:37 PM »
You make a reference font that same way you make a reference atlas, so you have one "Arial1" that links to either Arial20 or Arial40.

electrodruid

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 48
    • View Profile
Re: Font Maker and HD Atlases
« Reply #9 on: March 19, 2013, 07:11:37 PM »
Aha! The penny drops! I somehow completely missed the fact that you can make reference fonts as well as reference atlases. That suddenly makes much more sense!

EDIT: Okay, one last question about reference fonts and atlases - do people generally have a preference as to which atlases they put their fonts on? Putting them on the same atlas would seem to be good for minimising the number of draw calls, and for proper Z-ordering, but my colleagues have been mooting the idea of putting the fonts onto a seperate atlas of their own, so that there's less stuff to switch out if we need different fonts for different languages when it comes to localisation. Any thoughts on the pros and cons?

Nicki

  • Global Moderator
  • Hero Member
  • *****
  • Thank You
  • -Given: 33
  • -Receive: 141
  • Posts: 1,768
    • View Profile
Re: Font Maker and HD Atlases
« Reply #10 on: March 21, 2013, 06:42:36 AM »
Putting the fonts in the same atlas as everything else:
Pro
- Easier to handle depth
- fewer atlases, makes it easier to overview.

Con
- Can quickly get too big (max 2048x2048 on most touch devices)
- Makes you have an SD, HD, and UHD version of all your fonts; no re-use of font data.

Splitting sprites and fonts in two different atlases:
Pro
- You can reuse font data for different roles: ie: Arial20, arial40, arial80 - the arial 40 can be SD version of 80 and HD version of 20.
- Gives you more freedom to have many fonts, many sprites

Con
- makes depth confusing since multiple materials are used (you have to mess with the z-position)
- almost impossible to work with in a 3d gui


If you do dynamic fonts, you will do a variant of the latter, because they use their own material in any case - but dynamic fonts are not officially supported by NGUI yet, so be careful doing that. ;)