Pixel-Perfect Dynamic Text - Support Thread

Pixel-Perfect Dynamic Text for Unity.

LINK TO ASSET WEBSITE: Pixel-Perfect Dynamic Text website.
Also a “Lorem Ipsum”-demo version is available if you want to try the asset in Unity.

This asset has its own niche:
• it is meant for displaying pixel-perfect text (“crisp anti-aliasing”),
• camera-facing text (even when camera has free orientation in 3D),
• with size & position defined in world units (not in some “custom UI scale” or so).

When comparing Pixel-Perfect Dynamic Text (PPDT) to Unity’s built-in text components:
• “PPDT” is sharp with crisp anti-aliasing like the really old legacy built-in GUIText. (GUIText is from early days of Unity, many of you probably don’t even know what that is or was, but the text it rendered was nice and crisp).
• “PPDT” text is part of the 3D scene, in similar way as classic Text Mesh (which is also known as “3D Text”). But “PPDT” looks better than Text Mesh.
• No Canvas or Canvas Renderer is needed. “PPDT” is not part of the Unity’s UI system. The text is rendered by the regular Mesh Renderer component instead.

What features does Pixel-Perfect Dynamic Text have?

Most of the listed features are demonstrated in the interactive demo which also comes with the package as an example scene.

Text size is proportional to world units, and not dependent on screen size in pixels or dpi resolution.

  • For example, if you use an orthogonal camera in Unity with Size=5, it means the total height of window is 10 units. Pixel-Perfect Dynamic Text with unit size of 2.0 will mean one row takes vertically 20% of screen so that there will be space for 5 rows of text.

For maximum sharpness, pixel size for text font rendering is dynamically selected to be the nearest matching size for text world unit size.

  • For example, suppose your window height is 512 pixels and you have a camera like in the previous example. If you make a text with size 1.0, the row height will be 1 unit, corresponding to 51.2 pixels. The font will be rendered sharp with pixel size of 51.

Pixel-Perfect Dynamic Text component also works with both orthogonal and perspective cameras.

  • For perspective cameras, it measures distance from text object to the camera plane. With the power of trigonometry it figures out what is the correct pixel size for the text (with its current position and size, measured in world units).
  • This is done separately for each different piece of text with varying distances.

You can choose if text is pixel snapped to keep it sharp when it moves on screen.

  • With pixel snapping enabled, sub-pixel position of transform.position will be snapped to nearest pixel (of currently used screen resolution).

The Pixel-Perfect Dynamic Text component uses Unity’s internal font renderer and atlasing.

  • So you can use same fonts what you can use with the built-in Text Mesh or GUI Text — use custom truetype fonts.
  • Regular Font Styles are supported: normal, bold, italic, bold and italic.
  • Change color dynamically.
  • Standard built-in font material shader is used. No need for custom heavy-weight shaders.
  • Note: There’s no support for Rich Text with html-like syntax (for now, at least).

Text can be aligned and anchored, similar to how Unity’s built-in Text Mesh (3D Text) works.

  • Text can be left-, center- or right-aligned.
  • Horizontally text can be left-, center- or right-anchored.
  • Vertically text can be upper-, middle-, lower- or baseline-anchored. Pixel-Perfect Dynamic Text defaults to baseline anchoring for easier working with text (baseline anchor is not featured by built-in Text Mesh).

You can ask for font metrics and use tabs for alignment.

  • The component has baseline, ascent and descent properties.
  • You can also get size of the whole text (bounds of the generated mesh).
  • Tab size is defined in world units and tab char in text moves to the next tab stop.

The component contains many small tweaks to make it better.

  • Mesh is regenerated/reallocated only when necessary. E.g. when there’s longer text than previous frame, or if text properties change (size, style, anchor, alignment, …). Previous mesh arrays are reused when possible.
  • Pixel-Perfect Dynamic Text is compatible with dynamic batching. It can even combine with built-in text meshes as same font material and texture can be used with both.
  • You can update text dynamically, even every frame. See the last screen (10/10) of interactive demo. It has a “text mode” effect consisting of over 2000 characters updated every frame.
  • Aware of different texel sampling between graphics APIs, and adjusts as needed to keep your text sharp.
  • Automatically converts replaces existing Text Mesh objects if you add a new Pixel-Perfect Dynamic Text component to them.

No native code & small footprint.

  • Works with Desktop, Mobile and Web platforms.
    (probably with consoles as well, but we haven’t tried)
  • Supplied as a small DLL with the component and with bit of C# source for editor extension.
  • Works with Unity 6, 2023, 2022, 2021, 2020, 2019, 2018, 2017!

Pixel-Perfect Dynamic Text works also with Unity 2D.

  • NOTE: Default font material shader seems to render using the Default Sorting Layer with Order 0. To render sprites behind text, you can make a new Sorting Layer and drag it to be before Default. Or you can use Default Layer for your sprite but set the Order in Layer to negative value. And, of course, in similar way to force sprites render front of text.

NOTE: Tight integration with Unity GUI or other 3rd GUI libraries is not officially supported! As stated above, this asset has its own niche and is not meant to be a replacement for GUI libraries.

Check out more info and interactive demo in the Pixel-Perfect Dynamic Text website.

In addition to featuring the interactive demo, the website shows you a few examples what can often go wrong when you work with UI and text layouts between different screens. Also a few trade-offs and caveats are listed, and there’s a separate section for Questions and Answers.

The Pixel-Perfect Dynamic Text is now available - check out the home page!

New version has been submitted for review.

Latest changes:

// 2014-03-09, 1.0.2 - Added support for using a StringBuilder (textSB field).
// 2014-03-04, 1.0.1 - Fixed an unnecessary allocation when reusing mesh arrays.

So, essentially no more issues with GC (garbage collection)!

I’m really enjoying this plugin. It makes the text nice and crisp!

I know this might be a bit out of scope for the project, but it would be great if you could add some features to make this more of a general text solution.

Things like:

  • word wrapping
  • getting the position of a character or the exact width/height of the textbox (which seems to be incorrect/strange when I try to get it).
  • Richtext (which you mentioned in the description)

Either way - great extension!

Hi AndySum, great to hear you like Dynamic Text!

Can you elaborate on the problem you have with getting width/height of the text? You can test viewing of the current bounds in the editor by adding a Box Collider component (Component->Physics->Box Collider), and that shows the bounds are a tight fit for the generated text mesh. (Note that if you change the text and still have the box collider, you have to manually Reset the box collider to update it.)

There’s no any special code for the measurement. That is, the bounds returned by Dynamic Text is the same thing you get if you ask for bounds from the Mesh Filter.

I’d also like to have both of these, so they’re definitely feature candidates for future versions.

And version 1.0.2 is now available.

performance on mobile? and no source?

It works on mobile as well. There may be hickups in framerate when Unity’s font system needs to render new glyphs to the font atlas texture, but as long as the text size isn’t changing every frame, that shouldn’t matter (no need to regenerate anything in those frames). The pixel snapping is checked for on each OnUpdate() and the transform.position is snapped if it’s different from last frame (assuming the snapping is enabled). Source code isn’t included (component is in a dll file). Source code for the example scene is included of course.

No source = no sale, unfortunately.

1 Like

I may consider including source for the component itself at some point in the future. But for now it’s in dll form.

Anyone try this with NGUI? Will it work?

Unfortunately I don’t know how well Dynamic Text integrates with any of the UI packages like NGUI or Daikon Forge.

If you happen to have some UI which is built using Text Mesh then Dynamic Text should be quite easy to use as a replacement. (except if you need rich text)

Now the Dynamic Text home page has a “Lorem Ipsum”-demo version available for evaluation inside the Unity editor.

In the demo version your own text is not shown, but instead replaced with characters from the well known lorem ipsum text.

Hi Tonic,

This is a fantastic plugin. We have been using NGUI just for text because they were the only solution that gave us everything we needed. But NGUI’s rendering is very slow. Any animations involving text are very clunky. DynamicText is going to allow us to rip out NGUI altogether while still keeping draw calls low, and giving us most of the features we need. So thanks!

It is missing some of the bells and whistles of NGUI, like text wrapping and shrink to fit, but those would be easy to write ourselves if you added one feature: a method to get the size of a string of text in a given font and font size. Is this logic you already have in your class? If so, any possibility of exposing this publicly? Either that, or making the plugin open source?

Thanks

Thank you for the kind words!

The text wrapping etc. are things which I’m planning to add at some point, but I understand wanting to implement them yourselves if you need them urgently.

Currently you can get the generated text size by reading the DynamicText.bounds property (don’t read the bounds from mesh filter mesh). But note that due to few reasons, the mesh generation is deferred (it’s generated in the next Update, or in case of default Arial font, one additional frame to fix an on-device rarely occurring issue). So e.g. in Start() the bounds will still be zero-sized. This is a bit unfortunate, maybe I need to revisit this and see if I can make it work better in the future.

Using the size properly has come up a few times with other users as well, so I actually just made an example how to dynamically create dynamic text objects from array of prefabs, and how to align them after each other when the bounds are available. Here’s link to the example: http://strobotnik.com/temp/DT_aligned_text_array.unitypackage
(be sure to import the DynamicText package first)

If you more exactly want to know the size of text before actually creating one, unfortunately there’s no way to do that right now. I’m slightly reluctant to add it, since that method would need to do the full work similar to actually creating a text. That is, ask for Unity to add the glyphs in the asked size to the atlas texture (and if the atlas is full, this can potentially lead to flush of it and recreation of all other texts, so it is sometimes very slow). And after that a mesh would need to be generated, and only then the requested size of the text can be known.

To give an exact result, there is no shortcut for that. The text sizes can vary a bit depending on the font size and if hinting is used or not, and the exact sizes can be queried from the Unity font system only after the glyphs are actually added to the atlas. While I agree that asking for potential size is an important feature one would really want to have, in this case it’d also be very good if one could design the system not to need that. Otherwise some perhaps unnecessary queries can “pollute” the font atlas leading to a flush more often which would end up in worse performance.

That being said, I think there is a hackish workaround to do that now: you could just create a text with the wanted size but hide the mesh renderer, and then check how big the text ends up being.

All this might be possible to implement better if we’d have detailed access to font metrics through the Unity Font class. If somebody from Unity reads this, please expand the API… :wink:

Hi Tonic,

I bought a few days ago. I am very satisfied. but one thing missed.

Custom Soring Layer is impossible? I’m really really need that.

Thanks.

Ok, I looked around a bit. If you are trying to sort the text with sprites, and order the text to different order number than 0, try adding this component (SetSordingOrder.cs):

using UnityEngine;

[ExecuteInEditMode]
public class SetSortingOrder : MonoBehaviour
{
    public int sortingOrder;

    void Update()
    {
        renderer.sortingOrder = sortingOrder;
    }
}

Hope this helps. I’m not sure if this is exactly what you were after.

OK. i found a solution. :slight_smile:

check this.

https://github.com/nickgravelyn/UnityToolbag/tree/master/SortingLayer

if helped then adapt it next update. please

Thanks

This looks terrific. I have a question if you wouldn’t mind.

Is it possible to recognize each letter in a dynamic text string, and if generated in a scene, (for example, the work “cat”), Instantiate a specific prefab/gameObject based on each letter? So for example, there are 26 letters. If I had 26 prefabs, could I reference which letters were in a dynamic string and spawn the assigned prefabs at spawn points in the scene? Image a 3d landscape.

I hope that made sense. Thanks.

B.

Sure that’s possible. But that kind of thing is really out of the scope of this Dynamic Text asset. You probably should post your question to some more generic area of the forum.