[Unity] How to make font a Monospace Font with TextMeshPro (Very Easy!)
Watch on YouTubeVideo summary
The video addresses a common issue in game development where standard fonts cause text to shake when numbers change rapidly, as seen in games like Crypto Clickers. The creator explains that monospace fonts solve this by ensuring every character is evenly spaced, which stabilizes the display of changing values. While many aesthetically pleasing fonts do not look good when forced into a monospaced format, the tutorial demonstrates how to apply monospace spacing selectively to specific parts of the text using TextMeshPro. This approach allows developers to maintain the visual quality of their chosen fonts while ensuring that dynamic numbers remain steady and readable.
To achieve this effect, the presenter introduces an HTML tag called `mspace`, which controls the pixel distance between characters. The tutorial shows that applying this spacing to entire sentences often results in unnatural gaps, so it is best reserved for numeric values only. To implement this efficiently across a game, the creator develops a custom utility script containing an extension method. This method allows any integer, double, or other numeric type to be automatically converted into a formatted string with monospace tags applied around the number, eliminating the need to manually wrap every variable in HTML tags within the code.
The final demonstration compares a standard font with the new monospace solution while incrementing a counter by 250 units per second. The results clearly show that the version using the custom extension method has zero text shaking, whereas the standard version exhibits noticeable jitter. The creator concludes that this technique is highly recommended for any game featuring fluctuating numbers, as it significantly improves readability without compromising the overall design of the user interface. By combining TextMeshPro features with simple C# extension methods, developers can easily create a polished and stable numerical display system for their projects.
Read the full video transcript
So, one of the biggest complaints I get
in my games, well, with the current ones
that are out on the store such as
Compacto and Crypto Clickers, is the
fact that the fonts are not monospace.
If you don't know what monospace is,
it's basically every character is evenly
spaced between each other. So, the top
example here,
this font is monospaced. However, this
one is not. A lot of the cool-looking
fonts they can find out on the internet
don't look very nice
if they are monospaced. So, what if we
want to take a good-looking font like I
have in Idle Research, and we want to
make it monospace? Well, that's what I'm
about to show you in today's video.
So, this is my scene I have set up. I
have two sample text, and these are
TextMesh Pro text, by the ways.
Do not use the legacy text, and if you
haven't installed it, then make sure you
go to window, TextMesh Pro, import TMP
Essential Resources, and you're good
from there.
But anyways,
we can turn any font into a monospace
font. So, let's start with this first
example.
So, in order to apply monospace to our
font, in order to evenly space
everything out, we have to use this HTML
tag called mspace.
So, we just set it equal to our pixel
amount, which is like the amount of
pixels they're going to spread apart. If
you were set to 0.1,
everything's going to be on top of each
other. While if you have it set to 100
pixels, or maybe even 1,000,
everything's just going to be spaced
apart, and it looks kind of funny. So,
you could see it doesn't look great.
However, it reduces the shaking
if we were to have fast-increasing
numbers. And our goal would be to use
this for numbers only, because that's
generally the number that's always going
to be changing. So, that's where our
second example comes into play.
So, instead, we have our Mspace
opening HTML tag and then our closing
one around our number. So, this label
isn't affected and it's just a number.
And this looks more natural.
And if you wanted to, you could change
this number to whatever may look best. I
think 55 pixels will look best in this
situation. Let's implement it in our
script. So, I have one script called the
UI manager. So, this is where I'm going
to update my text and I'm going to
create another script called utilities.
And this can just stay in your assets
folder. It does not need to go onto your
scene. Since this script won't be going
into our scene, we can delete this mono
behavior and we don't need start and
update. So, in our utilities class,
we're going to be creating something
called an extension method. So, if you
don't know what that is, let me briefly
explain. Let's just say we have some
integer variable called some int and
it's equal to 40. So, let's say we have
a string variable called some string.
And we want to set our some string to
whatever some int is. So, we can just
set it to this.
When we do this, again, this is an
integer, we're going to get an error
saying that we cannot convert type int
to a type string. So, we have to use an
extension method that all ints have
called to string. And this basically
just converts it to a string. So, this
is an extension method and we're going
to be creating something like this. So,
this will be a public static string
method and it's static because we need
to use this outside of this utility
script in other scripts and it must be
static in order to create an extension
method. All right. So, as of right now,
it's just a normal static method. It's
not going to do anything and this will
not work as an extension method and it
returns an empty string.
So, to make this an extension method, we
have to pass in our first parameter as
this string original. So, when we say
this
back to the original example, this
refers to the variable it's being
extended from.
However, in order to do this, we have to
make this class static.
And let's say we want to apply this to
every string or number we have,
but we want to make a setting for it.
So, this can be controlled outside of
this class and method, but we'll just
make a variable called bool enabled. And
by default, we'll set it to true. So, if
we want to disable this mono space, we
can just set the enabled to false, and
it will just return the normal
string.
If the enabled is false,
then we're just going to return the
original string.
However,
we want to return
our m space tag
equal to however many pixels you want.
So, in my case, it looks good with 55,
so use 55.
And then original
and closing m space.
So, this dollar sign allows us to do
string interpolation, where we can add
variables inside of the string like we
did here.
So, let's say we have one string called
one, and let's just say it's some random
number 4,567.
And we have another string,
and we want to convert this into a mono
space string. So, it would be one.mono
space, and we're all done here.
So, if you want to disable this, we
would just type in false,
and it would return the original string.
So, we'll do testing in a bit, but let's
just say we have
an integer.
Right? So, let's change this one into an
int,
or maybe double. Let's do double. We
would see that we cannot resolve symbol
mono space.
What we can do here is accept
any kind of variable that isn't just a
string. So, we're going to convert this
into a generic method by adding the
carrot and the T here, where T
represents a generic, and a generic is
just any type of variable we give it.
So, it could be a string, int, double,
or any form of object. And we'll change
this original string into a T, so it's
just a generic. And additionally, when
we're returning our original string, if
this was disabled, we have to use that
two string extension method.
And we can simplify things by using the
ternary operator. So, what we can do is
that if it's enabled, we use question
mark, so this is our true statement, so
it's going to return this.
If it's false, it's going to return
the original like that. We can get rid
of this if statement. So, now it's a
one-liner,
and you can convert this to expression
body if you'd like. So, then it really
looks like a one-liner,
and it looks like that.
So, now we can accept any form of
variables. So, it can be a double,
it could be an int,
a float,
heck, even a byte if we wanted to. Now,
we can test this inside of our actual
game.
This will be a very basic script, so I'm
going to create two text variables for
our sample text. Additionally, I'm going
to create a double variable,
and we're going to increment this so we
can see that there's no more text
shaking.
So, for our sample one, the monospace
tag is going to be around the entire
text, while our sample text two is just
going to be the number. So, let me code
that up real quick.
All right, so here's our little script
here, and let me briefly explain what's
going on here. So, I have string
interpolation for both of these, and it
just says monospace and then our number.
And this N0 here is the equivalent of
two string with the N zero string
parameter. And this basically tells us
that this is going to be a decimal
number with zero decimals. And once it's
greater than a thousand, we're going to
add commas. And so for sample one, we
have our entire string and we apply the
monospace extension method. While for
the second one, we just apply it to our
number.
And at the bottom we increment this
number by 250 per second. So that's what
this time.deltaTime is. So this is going
to be adding to number 250 per second.
So let's save and apply our text to our
script and hit the play button.
So it looks very clean. There's no
shaking whatsoever.
And clearly the one on the bottom looks
much better because of the the label
looking kind of funky with monospace. So
this is good for numbers. I highly
recommend using it regardless of how big
this number is. There is no text shaking
whatsoever. So for sample one, let's
turn off the monospace and leave the
second one enabled. So you can kind of
see the difference. All right, so you
can see that this top one
shakes just a little bit. All right, so
here's the font from Crypto Clickers.
And as you can see, this is a major
yikes. You can see how badly that is
shaking.
So you can see there's no shaking
whatsoever in the monospace. It's kind
of starting to irritate me, so I'm just
going to stop playing. So that is it for
this video. Hopefully you've learned
something new. By the end of this video
you should be good with extension
methods, static methods, and Text Mesh
Pro. If you enjoyed the video and you
indeed learned something new, please
smash that like button as it really
helps out the video. And the daily
question for today is
what is your favorite Gatorade flavor?
Comment that down below and I'd say mine
is either lemon lime or
Ooh, I mean, I do have lemon lime the
most, but I'd have to think about that
one. Subscribe to the channel if you
haven't already, and if you want to
support the channel, check the Patreon.
It's in the description below. Join the
Discord server, and there's a thanks
button. So, if you want to support the
channel, hit that button as well. I hope
everyone has a wonderful day or night,
wherever you're at, and I'll see you all
in the next tutorial. Peace.