I'm searching a way to calculate "Best Fit" for UI Text myself

does anyone know how Unity calculates font sizes on the Text component when the “best fit” option is activated?I’m trying to bring a needle app to multiple devices (Desktop/Tablet/Smartphone) (Landscape/Portrait) and the text should be readable on all devices.

This is what I’m currently doing, but it’s wonky and it would be nice if I can use the text’s parent RectTransform values to calculate the font size.

awake(): void {
  if (this.checkForMobile()) {
      console.log("Mobile detected");
  else if (this.checkForTablet()) {
    this.portraitSizeMultiplier *= 1.5;
    this.landscapeSizeMultiplier *= 1.7;
    console.log("Tablet detected");
  else {
    this.portraitSizeMultiplier *= 2;
    this.landscapeSizeMultiplier *= 2;
    console.log("Desktop detected");
  if (this.isPortrait())
    this.textfield[i].fontSize = this.portraitSizeMultiplier * this.fontSize[i];
    this.textfield[i].fontSize = this.landscapeSizeMultiplier * this.fontSize[i];

Original Post on Discord

by user 334342083445784576

Hey :wave: that is definitely a missing feature overall, currently the screen space UI isn’t practically responsive.
Sadly it seems the “BestFit” implementation in Unity is in C++, so we can’t get a easy glimpse on what is going on there.

I think best would be to let the devs react on this one. Probably could become a feature request. :cactus:

We’re using three-mesh-ui for runtime UI and that has a best fit implementation. It may not be exposed through our Unity implementation right now but should be able to adjust the settings of underlying objects with code if needed.
The relevant sample ishttps://felixmariotto.github.io/three-mesh-ui/7.x.x/#ex__best_fit

@herbst🌵 could you show a quick example of how I would access the underlying three-mesh-ui from a Text component to setup Best Fit?

by user 300386587278049291

Hi @BMAN to access the underlying threemesh ui objects at the moment you can get hold of them via text.shadowComponent. Where text is a needle text component instance and shadow component is an object of tmui. You might need to iterate its hierarchy then to find the correct object to set the values on.

Every needle ui component has this shadowComponent field

Furthermore you can of course generate the ui from code as if youd be working with tmui directly - without using the needle engine ui components at all.

It seems like the shadowComponent is the TextElement from tmui, but bestFit needs set on the BlockElement parent of TextElement and I can’t seem to find that

by user 300386587278049291

Its in the children :slightly_smiling_face: they are nested a bit. When you log the shadowComponent you can check it in the console and find it in its children.

hmm the only child is an InlineElement

by user 300386587278049291

(which has a child Mesh)

by user 300386587278049291

@marcel :cactus: digging through the engine code it seems like UI elements become either TextElement or BlockElement, but TextElements are not added to a BlockElement

by user 300386587278049291

Just to clarify, I believe as currently structured the bestFit can’t be applied without a parent BlockElement

by user 300386587278049291

(I have 300+ Text elements in my scene and don’t want to swap them all for native tmui if I don’t have to)

by user 300386587278049291

Have you tried putting the created text element inside a Block? (You should be able to change the hierarchy as needed)

sorry I might need more hand holding if you’re willing - I’ve never worked with tmui before, I’m not sure how I would make a parent BlockElement to a shadowComponent.

by user 300386587278049291

This is what the TMUI sample for best fit does: three-mesh-ui/examples/ex__best_fit.js at 82945869e65c3f491a77c39bbb350716127f2abb · felixmariotto/three-mesh-ui · GitHub

Thanks for that link @marcel :cactus: , this has been a long rabbit hole and it turns out that bestFit was actually working, but their specific implementation for my use case wasn’t noticeable…not sure if you’ve ever looked under that hood but it’s a real head scratcher haha. I’m going to have to create my own. Thanks for your support as always!

by user 300386587278049291