Search Unity

[Unity5] Problem with CharacterInfo for runtime font creation

Discussion in 'Scripting' started by Deleted User, Mar 3, 2015.

  1. Deleted User

    Deleted User

    Guest

    So today I downloaded and installed Unity 5 to start adapting my code to the new changes and noticed a problem with CharacterInfo.

    I'm generating fonts from external data at runtime assigning all the info needed for the chars and create a new Font component out of it. It used to work with no problem before Unity 5, but now I'm getting a bunch of warnings about deprecated variables from CharacterInfo.

    I know that deprecated doesn't means that won't work but that will be stripped out in the future so I can still use my method but the problem is I can't adapt the code to the new stuff in CharacterInfo as it seems that half the variables are read only. Those are the warnings:

    `UnityEngine.CharacterInfo.uv' is obsolete: `CharacterInfo.uv is deprecated. Use uvBottomLeft, uvBottomRight, uvTopRight or uvTopLeft instead.'

    `UnityEngine.CharacterInfo.vert' is obsolete: `CharacterInfo.vert is deprecated. Use minX, maxX, minY, maxY instead.'

    `UnityEngine.CharacterInfo.width' is obsolete: `CharacterInfo.width is deprecated. Use advance instead.'

    `UnityEngine.CharacterInfo.flipped' is obsolete: `CharacterInfo.flipped is deprecated. Use uvBottomLeft, uvBottomRight, uvTopRight or uvTopLeft instead, which will be correct regardless of orientation.'

    So I would like to know if I can work around this.
     
    rakkarage and Ox_ like this.
  2. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    Yes. Instead of using uv, use uvBottomLeft, uvBottomRight, uvTopRight or uvTopLeft instead
    ...?
    Or just suppress warnings until it breaks
     
  3. Deleted User

    Deleted User

    Guest

    I can't use those as they are read only, thats where is the problem, almost all new variables in CharacterInfo are read only, so instead of a warning I'll get an error.
     
    rakkarage likes this.
  4. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    Ah, sorry! Must've missed that.
    Though... are you sure? The docs do not mention they are readonly
    http://docs.unity3d.com/ScriptReference/CharacterInfo.html

    compared to something like texture2d.width where it clearly states it is - may be an error in the docs if so

    I haven't installed U5 yet so i can't test. Just suppress warnings until the proper release of U5 (#pragma warning disable ####)
     
  5. Deleted User

    Deleted User

    Guest

    Yeah I'm sure, I get the error in th console if I try to assign, I was surprised too in the docs this wasn't stated thats why I was confused, this what I get:

    error CS0200: Property or indexer `UnityEngine.CharacterInfo.uvTopLeft' cannot be assigned to (it is read only)

    and same for the other vars. Well I guess I'll stick with what it works now and supress the warnings, thanks.
     
  6. Rasmus Selsmark

    Rasmus Selsmark

    Joined:
    Mar 13, 2013
    Posts:
    120
    Correct, these properties are read-only in code, but this is not documented. We'll make sure to fix this soon - we should see if we can somehow automatically detect that as part of documentation build...

    Hope you find a way to get rid of the warnings. You are welcome to post your code here.

    /Rasmus
     
  7. Elderkarma

    Elderkarma

    Joined:
    Nov 25, 2012
    Posts:
    1
    I have this issue as well. It's no longer possible to configure a custom CharacterInfo struct without using obsolete members. The replacement members are all read only.

    @Rasmus Selsmark do you refer to fixing the read-only issue, or just correcting documentation? CharacterInfo is rather crippled in its current form, and no alternate workflow seems available for creating custom font characters.
     
    almo, Ox_ and SpreadcampShay like this.
  8. Ox_

    Ox_

    Joined:
    Jun 9, 2013
    Posts:
    93
    Yes, please don't make it read-only.

    Also I'm trying to get the same values from the new properties and Y min/max values were changed:
    minX == vert.xMin == 6
    maxX == vert.xMax == 42
    But minY changed to -1 from 28.1 and maxY is now 42 instead of -15.8.

    How can I get the old ones without using deprecated code?

    Log code:
    Code (CSharp):
    1. Debug.Log("vert.w=" + charInfo.vert.width + " vert.x=" + charInfo.vert.x + " vert.xMin=" + charInfo.vert.xMin + " vert.xMax=" + charInfo.vert.xMax +
    2.                   "\nvert.h=" + charInfo.vert.height + " vert.y=" + charInfo.vert.y +" vert.yMin=" + charInfo.vert.yMin + " vert.yMax=" + charInfo.vert.yMax +
    3.                   "\nminX=" + charInfo.minX + " maxX=" + charInfo.maxX + " minY=" + charInfo.minY + " maxY=" + charInfo.maxY);
     
    almo likes this.
  9. Deleted User

    Deleted User

    Guest

    Well here is my font import method, is static method that reads from an external binary file serialized trough binary formatter and rebuild the font at runtime:

    Code (csharp):
    1.  
    2.  
    3.     #pragma warning disable 0618     //Get rid of ChracterInfo obsolete stuff warnings
    4.  
    5.      static public UnityEngine.Font ImportFont (string path)
    6.      {
    7.        string data = NM.IO.Path.GetExistingPath(path);
    8.    
    9.        NM.Format.Font m_font = Binary.ReadDynamicBinaryData<NM.Format.Font> (data);
    10.  
    11.        UnityEngine.Font font = new UnityEngine.Font (m_font.id);
    12.  
    13.        if(m_font != null && m_font.count > 0)
    14.        {
    15.          CharacterInfo[] m_chars = new CharacterInfo[m_font.count];
    16.      
    17.          for(int i = 0; i < m_chars.Length; i++)
    18.          {
    19.            m_chars[i].index = m_font.index[i];
    20.            m_chars[i].uv = new Rect(m_font.uv_x[i], m_font.uv_y[i], m_font.uv_w[i], m_font.uv_h[i]);
    21.            m_chars[i].vert = new Rect(m_font.vert_x[i], m_font.vert_y[i], m_font.vert_w[i], m_font.vert_h[i]);
    22.            m_chars[i].width = m_font.width[i];
    23.            m_chars[i].flipped = m_font.flipped[i];
    24.          }
    25.      
    26.          font.characterInfo = m_chars;
    27.  
    28.          Color32[] m_colors = new Color32[m_font.image_w * m_font.image_h];
    29.      
    30.          for(int i = 0; i < m_font.alpha.Length; i++)
    31.            m_colors[i] = new Color32(255, 255, 255, m_font.alpha[i]);
    32.  
    33.          Texture2D m_texture = new Texture2D (m_font.image_w, m_font.image_h);
    34.          m_texture.SetPixels32 (m_colors);
    35.          m_texture.Apply ();
    36.  
    37.          if(!Shader.Find (m_font.shader))
    38.            m_font.shader = "Unlit/Transparent";
    39.      
    40.          UnityEngine.Material m_material = new UnityEngine.Material(Shader.Find(m_font.shader));
    41.  
    42.          m_material.mainTexture = m_texture;
    43.          font.material = m_material;
    44.      
    45.        }
    46.        else
    47.          font = NM.Exception.nullFont(NM.IO.Path.fontPath + m_font.id + NM.IO.File.nmb);
    48.    
    49.        return font;
    50.      }
    51.  
    All the warnings are on the m_chars part. I should also agree with Elderkarma, when the obsolete vars are gone we are basicly out of creating fonts at runtime, so maybe open up something if is possible for the future.
     
    Last edited by a moderator: Mar 12, 2015
    almo likes this.
  10. Texaggie96

    Texaggie96

    Joined:
    Jan 23, 2009
    Posts:
    81
    I would like an answer to @Elderkarma question as well. Are you just going to fix the documentation or are you going to make the CharacerInfo members not read only? Making these read-only really destroys the editor bitmap font importer script. Please return these members to settable. Thanks.
     
    almo likes this.
  11. almo

    almo

    Joined:
    Jul 14, 2010
    Posts:
    83
    Oh no! I really need these to be writable!
     
  12. runestonegames

    runestonegames

    Joined:
    Dec 16, 2014
    Posts:
    98
    When is this issue going to be addressed?

    I would like to be able to script the creation of a custom bitmapped font - but am currently stuck with having to write code using deprecated members. WHY are the new accessors read only?

    Can @Rasmus Selsmark please answer the question posted properly: if the old variables are deprecated, and the new ones are read-only... how are we supposed to create custom fonts?
     
  13. majklCZ

    majklCZ

    Joined:
    Jun 29, 2013
    Posts:
    3
    Some, problem..instal new unity5 and my work is out...
     
    Last edited: Jun 22, 2015
  14. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    Just keep using the old members
    Suppress the warnings and you'll not even notice.
    Presumably they wont remove the deprecated properties without making the new one writable
     
  15. Texaggie96

    Texaggie96

    Joined:
    Jan 23, 2009
    Posts:
    81
    Is this being worked on? I don't see anything in the new road map regarding CharacterInfo or Font APIs. This really needs to be fixed ASAP. TTF fonts are not going to cut it with competition in the game engine market.
     
    zworp likes this.
  16. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,666
    Unity 5.2 will make all these new properties writeable.
     
  17. Deleted User

    Deleted User

    Guest

    Case solved I guess, now is only a matter to adjust the old stuff to the new properties. Will post back if I figure out how the new properties works related to the old.

    And thanks for the reply.
     
  18. Bravo_cr

    Bravo_cr

    Joined:
    Jul 19, 2012
    Posts:
    148
    I have start working on clearing all the warnings but I can't find the same data that I had before (I'm using unity 5.2).
    I have the exact same problem as Ox_ . The old values where floats and the new ones are integers. In my example if I use characterInfo.vert.y i t reads 31.23 and using characterInfo.maxY its 42. Anyone knows whats happening here?
     
    Last edited: Sep 11, 2015
  19. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,666
    Unity's text rendering system would always round values to pixel boundaries (integers), so having floats in these values was never actually a right decision. The new API fixes this.
     
  20. Bravo_cr

    Bravo_cr

    Joined:
    Jul 19, 2012
    Posts:
    148
    OK thanks for the answer. Everything I was doing in the previous api can be done in the new one, and its even simpler so many thanks.
     
  21. Gizmoi

    Gizmoi

    Joined:
    Jan 9, 2013
    Posts:
    327
    Did you manage to convert to the new system? I couldn't get maxX, minX, maxY and minY to be correct instead of using vert :(
     
  22. Deleted User

    Deleted User

    Guest

    Sadly not yet, same issue. Still trying to figre the math.
     
  23. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    This is not entirely correct
    Here is a textmesh + font with 2 of the glyphs having their vert values changed by 0.5f (width/height for #2, x and y for #8)

    While this particular font might not need float value precision, you can't remove this functionality for all fonts and always round to ints.
     
  24. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,666
    Well, ok, let me clarify. I wrote that "Unity's text rendering system would always round values to pixel boundaries (integers)". This is correct for any glyphs generated by Unity. Fonts Imported by or dynamically generated by Unity will always align characters to pixel boundaries. I guess, as your example shows, manually crafted fonts may actually have non-integer boundaries (which may be supported by accident - looking through our text rendering code, I found comments asking why we shouldn't switch it all to integers).

    So, question from me: Is anyone actually relying on being able to use non-integer values for these fields?
     
  25. MichelAlonso

    MichelAlonso

    Joined:
    Nov 10, 2014
    Posts:
    2
    If you are using the "xoffset", "yoffset", "width" and "height" of the glyph, try this:

    Code (CSharp):
    1.  
    2.   CharacterInfo charInfo = new CharacterInfo();
    3.   r = new Rect();
    4.   r.x = xoffset;
    5.   r.y = -yoffset;
    6.   r.width = width;
    7.   r.height = -height;
    8.  
    9.   // BEFORE
    10.   //charInfo.vert = r;
    11.   // AFTER
    12.   charInfo.minX = (int)r.xMin;
    13.   charInfo.maxX = (int)r.xMax;
    14.   charInfo.minY = (int)r.yMax;
    15.   charInfo.maxY = (int)r.yMin;
    16.