Is it possible to use an image font like Fontawesome? I’d love to have access to all those icons. I’m using them in my current UI via CoherentUI, but am changing my UI to built in 4.6 UI as it’s more reliable and will want to keep my icon usage.
Has no one tried this yet? I imported the font, but doesn’t appear functional.
I tried setting the font to Unicode and tried using the character code ( e.g. ), but it does nothing. Has anyone got custom fonts like this working?
Ok, the only way I could get it to work was to go to the fontawesome site, use the unicode cheatsheat, view the HTML source, copy the icon source, and paste it into the text field. This seams bonkers. Why won’t the unicodes work? The documentation says unicode is supported. What gives?
Ok I’ve tried all the following unicode usages and none of them work.
\f042 \uf042 \Uf042
I had to write a small script that on display parses it into the character. Is there no way to just use Unicode strings in the UI? If not how can I make a script extend the existing Text UI element with this capability? I looked into the reference documentation and looks like it’s using Graphics to draw it? Could a simple example be provided please.
Ok, Looks like there is no support for unicode even though documentation says there is. I’ve wrote the below tiny script that extends the Text type.
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Globalization;
namespace UnityEngine.UI
{
public class TextUnicode : Text
{
private Regex regexp = new Regex( @"\\u(?<Value>[a-zA-Z0-9]{4})" );
protected override void OnFillVBO( List<UIVertex> vbo )
{
if ( this.font == null ) {
return;
}
// Found no way to set this from here:
//this.m_DisableFontTextureChangedCallback = true;
Vector2 size = base.rectTransform.rect.size;
TextGenerationSettings generationSettings = this.GetGenerationSettings( size );
this.cachedTextGenerator.Populate( this.Decode( this.text ), generationSettings );
Rect rect = base.rectTransform.rect;
Vector2 textAnchorPivot = Text.GetTextAnchorPivot( this.alignment );
Vector2 zero = Vector2.zero;
zero.x = ( ( textAnchorPivot.x != 1f ) ? rect.xMin : rect.xMax );
zero.y = ( ( textAnchorPivot.y != 0f ) ? rect.yMax : rect.yMin );
Vector2 vector = base.PixelAdjustPoint( zero ) - zero;
IList<UIVertex> verts = this.cachedTextGenerator.verts;
float num = 1f / this.pixelsPerUnit;
if ( vector != Vector2.zero ) {
for ( int i = 0; i < verts.Count; i++ )
{
UIVertex item = verts[i];
item.position *= num;
item.position.x = item.position.x + vector.x;
item.position.y = item.position.y + vector.y;
vbo.Add( item );
}
} else {
for ( int j = 0; j < verts.Count; j++ )
{
UIVertex item2 = verts[j];
item2.position *= num;
vbo.Add( item2 );
}
}
// Found no way to set this from here:
//this.m_DisableFontTextureChangedCallback = false;
}
private string Decode( string value )
{
return regexp.Replace( value, m => ( (char) int.Parse( m.Groups["Value"].Value, NumberStyles.HexNumber ) ).ToString() );
}
}
}
You’d use Text Unicode instead of Text, which will parse the following Unicode usage out to its respective character.
\uf042
Be greatful to have some feedback from Unity to make this easier or at least please implement unicode parsing into next release. I’m not keen on the idea of having to replace all of that usage. It’d make more sense if I could just populate the TextGenerator with my parsed string instead of having to replace that entire output function.
Would it be possible for me to modify the text, call the parent OnFillVBO, then restore the text back? Would this work to avoid having to clone all this code? Could someone from Unity please chime in… how is unicode not working not a bigger deal…
Ok, I tried to make it more simple and came up with the following.
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Globalization;
namespace UnityEngine.UI
{
public class TextUnicode : Text
{
private Regex regexp = new Regex( @"\\u(?<Value>[a-zA-Z0-9]{4})" );
protected override void OnFillVBO( List<UIVertex> vbo )
{
string cache = this.text;
this.text = this.Decode( this.text );
base.OnFillVBO( vbo );
this.text = cache;
}
private string Decode( string value )
{
return regexp.Replace( value, m => ( (char) int.Parse( m.Groups["Value"].Value, NumberStyles.HexNumber ) ).ToString() );
}
}
}
It works, but the problem is it throws the following to the console.
Trying to add Text - Icon (UnityEngine.UI.TextUnicode) for graphic rebuild while we are already inside a graphic rebuild loop. This is not supported.
UnityEngine.Canvas:SendWillRenderCanvases()
Any ideas? Is this perhaps a bug?
Hi,
You can’t modify this.text inside a OnFIllVBO, that would cause a loop, since modifying this.text dirties the component and will call OnFillVBO again…
The ideal way would be to override the text setter, but unfortunately it’s not a virtual property, another way would be to modify m_Text field directly, but it’s private, so your class can’t access it as well.
So the current behaviour is by design, but the bug is that the text setter is not a virtual function you could override.
Could please file a bug on this?
I can suggest a workaround for now, its far from ideal, but it might work…
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Globalization;
namespace UnityEngine.UI
{
public class TextUnicode : Text
{
private disableDirty = false;
private Regex regexp = new Regex( @"\\u(?<Value>[a-zA-Z0-9]{4})" );
protected override void OnFillVBO( List<UIVertex> vbo )
{
string cache = this.text;
disableDirty = true;
this.text = this.Decode( this.text );
base.OnFillVBO( vbo );
this.text = cache;
disableDirty = false;
}
private string Decode( string value )
{
return regexp.Replace( value, m => ( (char) int.Parse( m.Groups["Value"].Value, NumberStyles.HexNumber ) ).ToString() );
}
public override void SetLayoutDirty()
{
if (disableDirty)
return;
base.SetLayoutDirty();
}
public override void SetVerticesDirty()
{
if (disableDirty)
return;
base.SetVerticesDirty();
}
public override void SetMaterialDirty()
{
if (disableDirty)
return;
base.SetMaterialDirty();
}
}
}
Cheers!
How would I go about doing that?
Awesome, thanks. Will give that a try when I’ve time (getting busy here for the holidays!).
Great, your proposal works. Below is the final script. If anyone wants to use it feel free. It basically just replaces the Text type with Text Unicode type, which will parse C# unicode strings.
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Globalization;
namespace UnityEngine.UI
{
public class TextUnicode : Text
{
private bool disableDirty = false;
private Regex regexp = new Regex( @"\\u(?<Value>[a-zA-Z0-9]{4})" );
protected override void OnFillVBO( List<UIVertex> vbo )
{
string cache = this.text;
disableDirty = true;
this.text = this.Decode( this.text );
base.OnFillVBO( vbo );
this.text = cache;
disableDirty = false;
}
private string Decode( string value )
{
return regexp.Replace( value, m => ( (char) int.Parse( m.Groups["Value"].Value, NumberStyles.HexNumber ) ).ToString() );
}
public override void SetLayoutDirty()
{
if ( disableDirty ) {
return;
}
base.SetLayoutDirty();
}
public override void SetVerticesDirty()
{
if ( disableDirty ) {
return;
}
base.SetVerticesDirty();
}
public override void SetMaterialDirty()
{
if ( disableDirty ) {
return;
}
base.SetMaterialDirty();
}
}
}
Is it possible support for unicode can be officially implemented? If not could a way to implement this without having to replace Text be added?
You can submit a bug from inside the editor (Help → Report a bug), this ensures issues doesn’t fall through cracks
I believe the issue here is not lack of unicode support… if you copy and paste the glyph, it will be shown in correctly i the Scene and Game view.
As I see right now, we have two issues:
- First is that the font we show in the Inspector is not the same in the Scene and Game view, this can be a bit confusing, since it’s possible that the glyph in the two fonts doesn’t match.
- Second is that we don’t support any way to input extended unicode characters besides copying and pasting.
I would need to investigate, and see how much impact would be to solve those issues.
Yeah, I noticed direct copy and paste worked, but then I could no longer see the character and if I typed something else it’d disappear. I believe that’s the issue you mentioned where the inspect font was not the same as the game font, but I think it’d be infinitely better to just add C# unicode or HTML unicode processing to the RichFont feature TBH.
I’ll file a report after installing the official 4.6 stable release.
Hey there!
Seems like this thread is a little old, but Leo do you have a status update on this?
It would be awesome to be allowed to type unicode directly in the Text field.
Great suggestion which I will incorporate in TextMesh Pro
I added support for typing Unicode character in the TextMesh Pro Text Input Box. The format is “\u00EF”. I could support alternative input formats if necessary.
Hehe that’s nice! Great addition.
But we also need native support for this in Unity UI
At the request of a user, I also added support for UTF-32. You can now create Font Assets using the built-in Font Asset Creator that contain UTF-32 glyphs / icons in the UTF-32 range.
You can now access these UTF-32 characters using the upper case U with 4 hex pairs. Example “\U0001F3A3” as seen in the example below
Note: Since the font that I generated only contained icons, I used the (soon to be released) tag to use a different font for the text and then switched back to font containing these icons using .
P.S. Since you use “\U0001F3A3” in strings as well as in the Text Input Box in TextMesh Pro, I didn’t see the need to add support for surrogate pairs given we can access the UTF-32 directly. So now in TextMesh Pro, you can use \u00AE to access UTF-16 and \U0001F3A3 for UTF-32.
I recently upgraded to Unity 5.2 (Pro) and it seems as if the original TextUnicode class has broken. The editor complains that line 21 of TextUnicode.cs:
base.OnFillVBO(vbo);
has been deprecated and OnPopulateMesh() should be used instead. Is there a workaround for this? Or rather…what’s the best way to convert a List vs into a Mesh object?