Tanoda
LetterSpacing.cs
Go to the documentation of this file.
1
3/*
4
5Produces an simple tracking/letter-spacing effect on UI Text components.
6
7Set the spacing parameter to adjust letter spacing.
8 Negative values cuddle the text up tighter than normal. Go too far and it'll look odd.
9 Positive values spread the text out more than normal. This will NOT respect the text area you've defined.
10 Zero spacing will present the font with no changes.
11
12Relies on counting off characters in your Text component's text property and
13matching those against the quads passed in via the verts array. This is really
14rather primitive, but I can't see any better way at the moment. It means that
15all sorts of things can break the effect...
16
17This component should be placed higher in component list than any other vertex
18modifiers that alter the total number of vertices. EG, place this above Shadow
19or Outline effects. If you don't, the outline/shadow won't match the position
20of the letters properly. If you place the outline/shadow effect second however,
21it will just work on the altered vertices from this component, and function
22as expected.
23
24This component works best if you don't allow text to automatically wrap. It also
25blows up outside of the given text area. Basically, it's a cheap and dirty effect,
26not a clever text layout engine. It can't affect how Unity chooses to break up
27your lines. If you manually use line breaks however, it should detect those and
28function more or less as you'd expect.
29
30The spacing parameter is measured in pixels multiplied by the font size. This was
31chosen such that when you adjust the font size, it does not change the visual spacing
32that you've dialed in. There's also a scale factor of 1/100 in this number to
33bring it into a comfortable adjustable range. There's no limit on this parameter,
34but obviously some values will look quite strange.
35
36This component doesn't really work with Rich Text. You don't need to remember to
37turn off Rich Text via the checkbox, but because it can't see what makes a
38printable character and what doesn't, it will typically miscount characters when you
39use HTML-like tags in your text. Try it out, you'll see what I mean. It doesn't
40break down entirely, but it doesn't really do what you'd want either.
41
42*/
43
44using System.Collections.Generic;
45
47{
48 [AddComponentMenu("UI/Effects/Extensions/Letter Spacing")]
51 public class LetterSpacing : BaseMeshEffect
52 {
53 [SerializeField]
54 private float m_spacing = 0f;
55
56 protected LetterSpacing() { }
57
58 #if UNITY_EDITOR
59 protected override void OnValidate()
60 {
61 spacing = m_spacing;
62 base.OnValidate();
63 }
64 #endif
65
66 public float spacing
67 {
68 get { return m_spacing; }
69 set
70 {
71 if (m_spacing == value) return;
72 m_spacing = value;
73 if (graphic != null) graphic.SetVerticesDirty();
74 }
75 }
76
77 public override void ModifyMesh(VertexHelper vh)
78 {
79 if (! IsActive()) return;
80
81 List<UIVertex> verts = new List<UIVertex>();
82 vh.GetUIVertexStream(verts);
83
84 Text text = GetComponent<Text>();
85 if (text == null)
86 {
87 Debug.LogWarning("LetterSpacing: Missing Text component");
88 return;
89 }
90
91 string[] lines = text.text.Split('\n');
92 Vector3 pos;
93 float letterOffset = spacing * (float)text.fontSize / 100f;
94 float alignmentFactor = 0;
95 int glyphIdx = 0;
96
97 switch (text.alignment)
98 {
99 case TextAnchor.LowerLeft:
100 case TextAnchor.MiddleLeft:
101 case TextAnchor.UpperLeft:
102 alignmentFactor = 0f;
103 break;
104
105 case TextAnchor.LowerCenter:
106 case TextAnchor.MiddleCenter:
107 case TextAnchor.UpperCenter:
108 alignmentFactor = 0.5f;
109 break;
110
111 case TextAnchor.LowerRight:
112 case TextAnchor.MiddleRight:
113 case TextAnchor.UpperRight:
114 alignmentFactor = 1f;
115 break;
116 }
117
118 for (int lineIdx=0; lineIdx < lines.Length; lineIdx++)
119 {
120 string line = lines[lineIdx];
121 float lineOffset = (line.Length -1) * letterOffset * alignmentFactor;
122
123 for (int charIdx = 0; charIdx < line.Length; charIdx++)
124 {
125 int idx1 = glyphIdx * 6 + 0;
126 int idx2 = glyphIdx * 6 + 1;
127 int idx3 = glyphIdx * 6 + 2;
128 int idx4 = glyphIdx * 6 + 3;
129 int idx5 = glyphIdx * 6 + 4;
130 int idx6 = glyphIdx * 6 + 5;
131
132 // Check for truncated text (doesn't generate verts for all characters)
133 if (idx6 > verts.Count - 1) return;
134
135 UIVertex vert1 = verts[idx1];
136 UIVertex vert2 = verts[idx2];
137 UIVertex vert3 = verts[idx3];
138 UIVertex vert4 = verts[idx4];
139 UIVertex vert5 = verts[idx5];
140 UIVertex vert6 = verts[idx6];
141
142 pos = Vector3.right * (letterOffset * charIdx - lineOffset);
143
144 vert1.position += pos;
145 vert2.position += pos;
146 vert3.position += pos;
147 vert4.position += pos;
148 vert5.position += pos;
149 vert6.position += pos;
150
151 verts[idx1] = vert1;
152 verts[idx2] = vert2;
153 verts[idx3] = vert3;
154 verts[idx4] = vert4;
155 verts[idx5] = vert5;
156 verts[idx6] = vert6;
157
158 glyphIdx++;
159 }
160
161 // Offset for carriage return character that still generates verts
162 glyphIdx++;
163 }
164 vh.Clear();
165 vh.AddUIVertexTriangleStream(verts);
166 }
167 }
168}
UnityEngine.Debug Debug
Definition: TanodaServer.cs:19
override void ModifyMesh(VertexHelper vh)
Credit Erdener Gonenc - @PixelEnvision.