void UpdateMesh() { if (Font == null || Size <= 0.0f || Text == null || Text.Length == 0) { // only use Text to flag this; we do want to keep the material // and TextData intact if the Font doesn't change if (m_PrevText != null) { // Text was cleared, nothing to render any more m_MeshFilter.mesh = null; m_PrevText = null; } return; } var rebuildMesh = false; if ((!m_PrevFont || !m_PrevFont.Equals(Font)) || !m_GeneratedFontData.IsCreated) { if (m_GeneratedFontData.IsCreated) { m_GeneratedFontData.Dispose(); } m_GeneratedFontData = FontAssetConversion.ConvertFontData(Font); m_PrevFont = Font; m_MeshRenderer.sharedMaterial = Font.material; rebuildMesh = true; } if (m_PrevSize != Size || m_PrevText != Text || m_PrevAlignment != Alignment || m_PrevColor != Color) { rebuildMesh = true; } if (!rebuildMesh) { return; } // Lay out the mesh in the same way that the runtime will do it var vdata = new NativeList <SimpleVertex>(128, Allocator.Temp); var idata = new NativeList <ushort>(128, Allocator.Temp); unsafe { fixed(char *chars = Text) TextLayout.LayoutString(chars, Text.Length, Size, Alignment, VerticalAlignment.Baseline, Color.ToTiny().AsFloat4(), ref m_GeneratedFontData.Value, vdata, idata, out AABB bbox); // Flip vdata.TexCoord0.y for Unity's UV direction. Do this here to make // it easier to have two different paths below. for (int i = 0; i < vdata.Length; ++i) { ref var item = ref vdata.ElementAt(i); item.TexCoord0.y = 1.0f - item.TexCoord0.y; } }