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.
  2. Dismiss Notice

Question Button text size in % doesn't work

Discussion in 'UI Toolkit' started by aganm, Jan 12, 2021.

  1. aganm

    aganm

    Joined:
    Sep 25, 2019
    Posts:
    114
    I'm trying to make a button whose text will stay the same size relative to the screen. For example, if the user has a 720p screen, the button will take 30% of the height of the screen. If it's a 1080p screen, the button font size will still take 30% of the height of the screen.

    I tried by setting the button text size in percentage with a value of 30%.

    upload_2021-1-12_8-30-28.png

    When I resize my game screen, my sections are properly resized at the percentage value I set them (green and red sections taking 50% of the screen each no matter the resolution). But the text of the button doesn't, it doesn't scale.
     
    Sebseb_ and RKar like this.
  2. aganm

    aganm

    Joined:
    Sep 25, 2019
    Posts:
    114
  3. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    1,256
    The builder isn't a good place to test this. Try at runtime and see the results.
     
  4. aganm

    aganm

    Joined:
    Sep 25, 2019
    Posts:
    114
    I did try both in the builder and in runtime with the same behavior. Thanks for the suggestion.
     
  5. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,203
    Font Size does not currently support the % unit. We're aware of this limitation but are hoping to fix it soon.

    Both UI Builder and USS will allow you to set font size with a % unit because they both rely on our validation syntax which assumed % was supported. We can't undo that now because it might cause existing USS to generate errors. We'll have to wait for the proper fix.
     
    Snotax, aganm and Kazko like this.
  6. MousePods

    MousePods

    Joined:
    Jul 19, 2012
    Posts:
    753
    Is this support coming soon?
     
    OMGOMGXAXA and abhijithkumar123 like this.
  7. AaronBalint

    AaronBalint

    Joined:
    Aug 6, 2021
    Posts:
    1
    +1 for % text size support
     
    zzxiang and abhijithkumar123 like this.
  8. abhijithkumar123

    abhijithkumar123

    Joined:
    May 28, 2021
    Posts:
    1
    Please implement '% for text size'. We desperately need this!
     
    zzxiang likes this.
  9. hot-knife-digital

    hot-knife-digital

    Joined:
    Oct 22, 2013
    Posts:
    12
    Please implement!
     
  10. thiedemike50

    thiedemike50

    Joined:
    Jul 31, 2021
    Posts:
    2
    Please implement this ... or is there currently another way to achieve text scale?
     
    wbourchier and sharkbitgamesdev like this.
  11. anuj

    anuj

    Joined:
    Jun 15, 2015
    Posts:
    28
    Please try this, I managed it in this way to dynamically change font size
    Code (CSharp):
    1.  
    2. public UIDocument uiDoc; // assign it in inspector
    3. private VisualElement root;
    4.  
    5. private void Awake()
    6. {
    7. root = uiDoc.rootVisualElement;
    8.  
    9. // using Button here but you can use any visual element with //text
    10. Button btn = root.Q<Button>("myButton");
    11. string btnText = btn.text;
    12.  
    13. float btnWidth = btn.resolvedStyle.width;
    14.  
    15. IStyle style = btn.style;
    16. style.fontSize = new   StyleLength (btnWidth / btnText.Length);
    17.  
    18. btn.style.fontSize = style.fontSize;
    19.  
    20. }
     
    Last edited: Jan 14, 2022
  12. Snotax

    Snotax

    Joined:
    Jan 28, 2019
    Posts:
    14
    +1 for % text size support
     
    KAJed likes this.
  13. ivank

    ivank

    Joined:
    Nov 16, 2013
    Posts:
    97
    +1 for % text size support
     
    KAJed and Randolphjand like this.
  14. Digital_Mimesis_Lab

    Digital_Mimesis_Lab

    Joined:
    Mar 9, 2022
    Posts:
    24
    + 1 for % text size support
     
    KAJed likes this.
  15. JoNax97

    JoNax97

    Joined:
    Feb 4, 2016
    Posts:
    611
    @uDamian Has been any news about this? We really need an equivalent of TMPro's 'auto-size before we can adopt UI Toolkit
     
    Sebseb_ likes this.
  16. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,203
    There have been some explorations on this, and it's in our backlog, but no ETA at this time.
     
    JoNax97 likes this.
  17. florianBrn

    florianBrn

    Joined:
    Jul 31, 2019
    Posts:
    53
    I can't understand why this isn't a top priority, since it makes it impossible to use UI Toolkit for responsive UIs.
     
    ivank, lemmons and Spectragate like this.
  18. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,203
    I don't think it makes it impossible to create responsive UIs, just more tedious and difficult. If you have a specific use case, please share it, and we'll do our best to suggest workarounds.

    As for why it's not top-priority, I can't give a very detailed answer, but suffice it to say that we have larger issues that affect more users which makes them the current top-priorities. As we slowly get these addressed, we will eventually get to this issue as well.
     
  19. noise_source

    noise_source

    Joined:
    May 4, 2015
    Posts:
    17
    Please fix this. It's a nightmare.
     
  20. dlorre

    dlorre

    Joined:
    Apr 12, 2020
    Posts:
    700
    There are CSS units vh, vw and vmin. As for responsive UI you can do that with the geometrychange event. Hopefully I can publish my UI package soon but as it is now it is way too complicated. Also if you start using geometry change events you are on your own because the UI designer won't be of any help.
     
  21. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,203
    You mean UI Builder? How so? GeometryChangeEvents should still work in the UI Builder. It's true it's not nearly as simple as just giving your font a % size, but if you wrap this logic in a custom VisualElement (with UXML support), you can use it in the UI Builder. Let us know if you're running into problems.
     
  22. dlorre

    dlorre

    Joined:
    Apr 12, 2020
    Posts:
    700
    I use geometry change events in a document controller script, so that I can make responsive classes. For example if I put width 10% and add the class w2h then the height will be computed from the width. It works but the UI Builder does not understand this logic. On the other hand it works with any VisualElement, not just custom ones.

    My goal is to remove every reference to px in uss, but it does not work in a few cases like font size so for this I use separate stylesheets.
     
  23. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,203
    Ya, you could make this work by embedding that logic inside a wrapper/container-type custom VisualElement that will work in the UI Builder. I'm just saying it should be possible.
     
  24. dlorre

    dlorre

    Joined:
    Apr 12, 2020
    Posts:
    700
    I'm using uss classes to control the ratio so it's not an option here:

    Code (csharp):
    1.  
    2.         public static void prepareRatio(VisualElement el)
    3.         {
    4.             if (el.ClassListContains("h2w") || el.ClassListContains("w2h") || el.ClassListContains("w2h-child") ||
    5.                 el.ClassListContains("font-size") || el.ClassListContains("round-corner") || el.ClassListContains("button-image") ||
    6.                 el.ClassListContains("unity-toggle__checkmark") || el.ClassListContains("unity-radio-button__checkmark") || el.ClassListContains("unity-radio-button__checkmark-background"))
    7.             {
    8.                 el.RegisterCallback<GeometryChangedEvent>(adjustRatio);
    9.             }
    10.             foreach (var child in el.Children())
    11.             {
    12.                 prepareRatio(child);
    13.                 adjustRatio(child);
    14.             }
    15.         }
    16.  
     
  25. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,203
    Still not too sure why this wouldn't work in the UI Builder. All UITK code is still running inside elements inside the UI Builder Canvas. If you put the above logic in a custom VisualElement "container" (where you put all of the rest of your UI), that runs it on GeometryChangeEvent registered on itself, it should work.
     
    dlorre likes this.
  26. dlorre

    dlorre

    Joined:
    Apr 12, 2020
    Posts:
    700
    Yes, I didn't think of putting this in a container, I am applying the function to the rootVisualElement from the UIDocument controller.
     
  27. Sebseb_

    Sebseb_

    Joined:
    Feb 23, 2016
    Posts:
    3
    Hi ! Do you have any update on this issue ? And do you have a reliable workaround to give ? Indeed it is a bit confusing to have the option to put "%" as a unit while it is known it doesn't work
     
    Salim likes this.
  28. Salim

    Salim

    Joined:
    Apr 25, 2011
    Posts:
    148
    Hi! I just want to add myself to the people that needs this. Thank you :)
     
  29. dlorre

    dlorre

    Joined:
    Apr 12, 2020
    Posts:
    700
    I have posted this already but this is how you can adapt your font size to the display:

    Code (csharp):
    1.  
    2.        virtual protected void Awake()
    3.         {
    4.             geoStyle = defaultGeometryStyleSheet;
    5.             inputController = InputController.Instance;
    6.         }
    7.  
    8.  
    9.         virtual protected void OnEnable()
    10.         {
    11.  
    12.             isDirty = true;
    13.  
    14.             root = GetComponent<UIDocument>().rootVisualElement;
    15.             top = root.parent;
    16.  
    17.             top.styleSheets.Add(defaultGeometryStyleSheet);
    18.  
    19.             root.RegisterCallback<GeometryChangedEvent>(ev =>
    20.             {
    21.                 if (ev.oldRect.width == ev.newRect.width && ev.oldRect.height == ev.newRect.height)
    22.                 {
    23.                     return;
    24.                 }
    25.                 if (ev.newRect.width == 0 || ev.newRect.height == 0)
    26.                 {
    27.                     return;
    28.                 }
    29.  
    30.                 top.styleSheets.Remove(geoStyle);
    31.  
    32.                 if (ev.newRect.width > 2048)
    33.                 {
    34.                     geoStyle = largeGeometryStyleSheet;
    35.                 }
    36.                 else if (ev.newRect.width < 1024)
    37.                 {
    38.                     geoStyle = tinyGeometryStyleSheet;
    39.                 }
    40.                 else
    41.                 {
    42.                     geoStyle = defaultGeometryStyleSheet;
    43.                 }
    44.                 top.styleSheets.Add(geoStyle);
    45.  
    46.                 if (isDirty)
    47.                 {
    48.                     isDirty = false;
    49.                     Utility.prepareRatio(root);
    50.                 }
    51.             });
    52. ...
    53.  
    Then you put the relevant font size in the various style sheets.
     
  30. jakob-leitner

    jakob-leitner

    Joined:
    Nov 11, 2020
    Posts:
    16
  31. Gekigengar

    Gekigengar

    Joined:
    Jan 20, 2013
    Posts:
    705
    Hi, I am still experiencing this issue. Text does not seem to resize when put to %. I assume this feature has been implemented somewhere along the 1 year gap of this post and somehow the feature regressed?

    Using 2022.2.0b8.
     
  32. MousePods

    MousePods

    Joined:
    Jul 19, 2012
    Posts:
    753
    It has not been implemented.
     
  33. Gekigengar

    Gekigengar

    Joined:
    Jan 20, 2013
    Posts:
    705
    No way.. Its almost 2 whole years if you count this post started since Jan 2021. o_O
     
  34. Nicolas_Granese

    Nicolas_Granese

    Joined:
    Mar 25, 2020
    Posts:
    5
    Unity version 2021.3.12f1 and nothing yet
     
  35. ArnaudJopart

    ArnaudJopart

    Joined:
    Oct 27, 2016
    Posts:
    13
    Hi there.
    Can the UI document panel setting not do the trick to adapt labels the screen size? It has a scale mode similar to our good old canvas preventing text to become huge on mobile and tiny on 4K monitors. Hope it can help someone.
    Cheers
     

    Attached Files:

    jvcoqui and CodeSmile like this.
  36. grrava

    grrava

    Joined:
    Nov 11, 2012
    Posts:
    36
    +1 for this feature, still not supported in 2022.2.1f1. I now have to implement different styles for portrait and landscape mode, just for the font size...
     
  37. ivank

    ivank

    Joined:
    Nov 16, 2013
    Posts:
    97
    Hi @uDamian , just joining the crowd here - seriously, is there any progress, a chance that the "implementation % for text size" feature will get an appropriate attention any time soon?
    I have to say it is unbelievably annoying issue one runs into - and has to deal with somehow - almost *every* time when dealing with UI toolkit :(
    Sorry for the rant, but after two years this should be addressed somehow...
     
  38. oktayturkdagli

    oktayturkdagli

    Joined:
    Jan 28, 2020
    Posts:
    4
    This is truly incredible. I thought one of Unity's most powerful features was its crossplatform capability. Therefore, it is expected to be easy to prepare for the interface that can work at different screen resolutions.

    But I can't work at different resolutions just because I can't value fonts on a percentage basis. As far as I researched, there is no 3rd party solution. It looks like I have to use uGUI.

    Any idea how to solve this problem?

    Are you doing any development on this topic?
     
  39. shenanigans

    shenanigans

    Joined:
    Mar 28, 2014
    Posts:
    4
    `vh` and `vw` units are pretty core to the way people write CSS these days. What's the point of basing a project on an existing ecosystem if you aren't going to onboard lessons learned? What's the point of building a GUI with a static text document if that document has to be corrected every time it's loaded?

    And btw, how long until Unity once again possesses a component that's not either deprecated or not ready?
     
    Mushakushi, Sara_01 and ELWATONA like this.
  40. Mushakushi

    Mushakushi

    Joined:
    Jul 5, 2018
    Posts:
    14
  41. CitrioN

    CitrioN

    Joined:
    Oct 6, 2016
    Posts:
    66
  42. Sara_01

    Sara_01

    Joined:
    Nov 20, 2020
    Posts:
    5
  43. unity_C8608CA02CE5D98B3CA2

    unity_C8608CA02CE5D98B3CA2

    Joined:
    Dec 19, 2022
    Posts:
    1
    +1 looking for a solution. Super excited to use this feature and now it is not useable at all.
     
    Last edited: Feb 27, 2023
  44. makkenr95

    makkenr95

    Joined:
    Sep 2, 2013
    Posts:
    7
    Have there been any update on the UI Builder USS text size in percentage? Its been a couple of years now and its one of the most important features in the tool.

    I saw the #11 comment in this post. Is that the best way to create responsive UI text depending on its element? And i dont think that works with multiple lines of text without creating your own text wrap function as well
     
    Last edited: Mar 7, 2023
  45. dlorre

    dlorre

    Joined:
    Apr 12, 2020
    Posts:
    700
    I gave up on that and solved the issue by using Scale With Screen Size in PanelSettings, just like they do in Dragon Crashers. It makes my code easier to maintain and I can use px in my uss files.

    upload_2023-3-7_16-5-52.png
     
  46. makkenr95

    makkenr95

    Joined:
    Sep 2, 2013
    Posts:
    7
    The 4K ppl are gonna hate us but i guess this is the way :(
     
  47. Mushakushi

    Mushakushi

    Joined:
    Jul 5, 2018
    Posts:
    14
    I made a pretty straightforward script that should serve as a good starting point to solve this issue, which was heavily inspired by some examples shown in this Unity Answers thread. It should work with every TextElement in theory (I've only tested with my two main use cases, Labels and Buttons, and it works great .... button alignment does become broken with this approach though. Hopefully someone with more knowledge on this issue can chime in).

    First you need this class that resizes any text element's font size with respect to its content rect (ie. scaling font size based on %):
    Code (CSharp):
    1.  
    2.     /// <summary>
    3.     /// Resizes a <see cref="TextElement"/> font size with respect to its <see cref="VisualElement.contentRect"/>.
    4.     /// </summary>
    5.     public static class TextElementAutoFitter
    6.     {
    7.         /// <summary>
    8.         /// Registers callbacks for the <see cref="TextElement"/> to update its font size.
    9.         /// </summary>
    10.         public static void RegisterAutoFitCallbacks(TextElement textElement)
    11.         {
    12.             textElement.RegisterCallback<AttachToPanelEvent, TextElement>(OnAttachToPanel, textElement);
    13.             textElement.RegisterCallback<DetachFromPanelEvent, TextElement>(OnDetachFromPanel, textElement);
    14.         }
    15.  
    16.         private static void OnAttachToPanel(AttachToPanelEvent _, TextElement textElement)
    17.         {
    18.             textElement.RegisterCallback<ChangeEvent<string>, TextElement>(OnChange, textElement);
    19.             textElement.RegisterCallback<ChangeEvent<StyleFont>, TextElement>(OnChange, textElement);
    20.             textElement.RegisterCallback<ChangeEvent<StyleFontDefinition>, TextElement>(OnChange, textElement);
    21.             textElement.RegisterCallback<ChangeEvent<StyleLength>, TextElement>(OnChange, textElement);
    22.             textElement.RegisterCallback<GeometryChangedEvent, TextElement>(OnChange, textElement);
    23.             textElement.UnregisterCallback<AttachToPanelEvent, TextElement>(OnAttachToPanel);
    24.             // and any other callbacks that may impact scaling that I may have missed
    25.         }
    26.  
    27.         private static void OnDetachFromPanel(DetachFromPanelEvent _, TextElement textElement)
    28.         {
    29.             textElement.UnregisterCallback<ChangeEvent<string>, TextElement>(OnChange);
    30.             textElement.UnregisterCallback<ChangeEvent<StyleFont>, TextElement>(OnChange);
    31.             textElement.UnregisterCallback<ChangeEvent<StyleFontDefinition>, TextElement>(OnChange);
    32.             textElement.UnregisterCallback<ChangeEvent<StyleLength>, TextElement>(OnChange);
    33.             textElement.UnregisterCallback<GeometryChangedEvent, TextElement>(OnChange);
    34.             textElement.UnregisterCallback<DetachFromPanelEvent, TextElement>(OnDetachFromPanel);
    35.         }
    36.  
    37.         /// <summary>
    38.         /// Resize the text element when geometry is changed.
    39.         /// </summary>
    40.         private static void UpdateFontSize(TextElement textElement)
    41.         {
    42.             if (textElement.text == string.Empty) return;
    43.      
    44.             var textSize = textElement.MeasureTextSize(
    45.                 textElement.text,
    46.                 textElement.contentRect.width,
    47.                 VisualElement.MeasureMode.Undefined,
    48.                 textElement.contentRect.height,
    49.                 VisualElement.MeasureMode.Undefined
    50.             );
    51.             var fontSize = Mathf.Max(textElement.resolvedStyle.fontSize, 1);
    52.             var targetFontSize = Mathf.FloorToInt(Math.Max(
    53.                 Mathf.Min(Mathf.Abs(textElement.contentRect.height / textSize.y * fontSize), Mathf.Abs(textElement.contentRect.width / textSize.x * fontSize)), 1
    54.             ));
    55.      
    56.             if (Mathf.FloorToInt(textSize.y) == targetFontSize) return;
    57.             textElement.style.fontSize = new StyleLength(new Length(targetFontSize));
    58.         }
    59.  
    60.         /// <summary>
    61.         /// Generic callback handler use to <see cref="UpdateFontSize"/>.
    62.         /// </summary>
    63.         /// <typeparam name="TEvent"></typeparam>
    64.         private static void OnChange<TEvent>(TEvent eventBase, TextElement textElement) where TEvent: EventBase<TEvent>, new()
    65.         {
    66.             // eventBase.StopPropagation(); I don't think this is needed but leaving it in
    67.             UpdateFontSize(textElement);
    68.         }
    69.     }
    70.  
    It can be used to auto-size a label like this:
    Code (CSharp):
    1.  
    2. /// <summary>
    3. /// Auto-sizing <see cref="Label"/>.
    4. /// </summary>
    5. public class LabelAutoFit : Label
    6. {
    7.     [UnityEngine.Scripting.Preserve] public new class UxmlFactory : UxmlFactory<LabelAutoFit, UxmlTraits>{}
    8.  
    9.     public LabelAutoFit() => TextElementAutoFitter.RegisterAutoFitCallbacks(this);
    10. }
    11.  
    And for our desired use case, buttons:
    Code (CSharp):
    1.  
    2. /// <summary>
    3. /// Auto-sizing <see cref="Button"/>.
    4. /// </summary>
    5. public class ButtonAutoFit: Button
    6. {
    7.     [UnityEngine.Scripting.Preserve]
    8.     public new class UxmlFactory : UxmlFactory<ButtonAutoFit, UxmlTraits>
    9.     {
    10.         public override string uxmlNamespace => "Custom"; // neat tip for anyone who doesn't know
    11.     }
    12.  
    13.     public ButtonAutoFit(Action clickEvent) : base(clickEvent)
    14.     {
    15.         TextElementAutoFitter.RegisterAutoFitCallbacks(this);
    16.         // bug - button alignment becomes broken
    17.         style.unityTextAlign = new StyleEnum<TextAnchor>(TextAnchor.UpperCenter);
    18.     }
    19.     public ButtonAutoFit(): this(null) {}
    20. }
    21.  
     
  48. DREBOTgamestudio

    DREBOTgamestudio

    Joined:
    Jan 30, 2018
    Posts:
    66
    How many years do we have to wait for autoscale text? It really kills the ability to use the UI Toolkit.
     
    Mauschelbaer, curbol and ivank like this.
  49. Mortidio

    Mortidio

    Joined:
    Jan 30, 2023
    Posts:
    1
    + 1 for % text size support

    Pretty please

    I will probably implement it in the code using the examples here... but - it is still several hours of codewriting and testing vs.putting in number and and selecting % and moving on with the tasks...
     
    Mauschelbaer likes this.
  50. pgs1000

    pgs1000

    Joined:
    Mar 25, 2022
    Posts:
    2
    Not having % text size support is a pain.
     
    Mauschelbaer and GDevTeam like this.