Tanoda
MonoSpacing.cs
Go to the documentation of this file.
1
3/*
4
5Produces an simple mono-spacing effect on UI Text components.
6
7Set the spacing parameter to adjust mono 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/Mono Spacing")]
49 [RequireComponent(typeof(Text))]
50 [RequireComponent(typeof(RectTransform))]
53 public class MonoSpacing : BaseMeshEffect
54 {
55 [SerializeField]
56 private float m_spacing = 0f;
57 public float HalfCharWidth = 1;
58 public bool UseHalfCharWidth = false;
59
60 private RectTransform rectTransform;
61 private Text text;
62
63 protected MonoSpacing() { }
64
65 protected override void Awake()
66 {
67 text = GetComponent<Text>();
68 if (text == null)
69 {
70 Debug.LogWarning("MonoSpacing: Missing Text component");
71 return;
72 }
73 rectTransform = text.GetComponent<RectTransform>();
74 }
75
76 #if UNITY_EDITOR
77 protected override void OnValidate()
78 {
79 Spacing = m_spacing;
80 base.OnValidate();
81 }
82 #endif
83
84 public float Spacing
85 {
86 get { return m_spacing; }
87 set
88 {
89 if (m_spacing == value) return;
90 m_spacing = value;
91 if (graphic != null) graphic.SetVerticesDirty();
92 }
93 }
94
95 public override void ModifyMesh(VertexHelper vh)
96 {
97 if (! IsActive()) return;
98
99 List<UIVertex> verts = new List<UIVertex>();
100 vh.GetUIVertexStream(verts);
101
102 string[] lines = text.text.Split('\n');
103 // Vector3 pos;
104 float letterOffset = Spacing * (float)text.fontSize / 100f;
105 float alignmentFactor = 0;
106 int glyphIdx = 0;
107
108 switch (text.alignment)
109 {
110 case TextAnchor.LowerLeft:
111 case TextAnchor.MiddleLeft:
112 case TextAnchor.UpperLeft:
113 alignmentFactor = 0f;
114 break;
115
116 case TextAnchor.LowerCenter:
117 case TextAnchor.MiddleCenter:
118 case TextAnchor.UpperCenter:
119 alignmentFactor = 0.5f;
120 break;
121
122 case TextAnchor.LowerRight:
123 case TextAnchor.MiddleRight:
124 case TextAnchor.UpperRight:
125 alignmentFactor = 1f;
126 break;
127 }
128
129 for (int lineIdx=0; lineIdx < lines.Length; lineIdx++)
130 {
131 string line = lines[lineIdx];
132 float lineOffset = (line.Length - 1) * letterOffset * (alignmentFactor) - (alignmentFactor - 0.5f) * rectTransform.rect.width;
133
134 var offsetX = -lineOffset + letterOffset / 2 * (1 - alignmentFactor * 2);
135
136 for (int charIdx = 0; charIdx < line.Length; charIdx++)
137 {
138 int idx1 = glyphIdx * 6 + 0;
139 int idx2 = glyphIdx * 6 + 1;
140 int idx3 = glyphIdx * 6 + 2;
141 int idx4 = glyphIdx * 6 + 3;
142 int idx5 = glyphIdx * 6 + 4;
143 int idx6 = glyphIdx * 6 + 5;
144
145 // Check for truncated text (doesn't generate verts for all characters)
146 if (idx6 > verts.Count - 1) return;
147
148 UIVertex vert1 = verts[idx1];
149 UIVertex vert2 = verts[idx2];
150 UIVertex vert3 = verts[idx3];
151 UIVertex vert4 = verts[idx4];
152 UIVertex vert5 = verts[idx5];
153 UIVertex vert6 = verts[idx6];
154
155 // pos = Vector3.right * (letterOffset * (charIdx) - lineOffset);
156 float charWidth = (vert2.position - vert1.position).x;
157 var smallChar = UseHalfCharWidth && (charWidth < HalfCharWidth);
158
159 var smallCharOffset = smallChar ? -letterOffset/4 : 0;
160
161 vert1.position += new Vector3(-vert1.position.x + offsetX + -.5f * charWidth + smallCharOffset, 0, 0);
162 vert2.position += new Vector3(-vert2.position.x + offsetX + .5f * charWidth + smallCharOffset, 0, 0);
163 vert3.position += new Vector3(-vert3.position.x + offsetX + .5f * charWidth + smallCharOffset, 0, 0);
164 vert4.position += new Vector3(-vert4.position.x + offsetX + .5f * charWidth + smallCharOffset, 0, 0);
165 vert5.position += new Vector3(-vert5.position.x + offsetX + -.5f * charWidth + smallCharOffset, 0, 0);
166 vert6.position += new Vector3(-vert6.position.x + offsetX + -.5f * charWidth + smallCharOffset, 0, 0);
167
168 if (smallChar)
169 offsetX += letterOffset / 2;
170 else
171 offsetX += letterOffset;
172
173 verts[idx1] = vert1;
174 verts[idx2] = vert2;
175 verts[idx3] = vert3;
176 verts[idx4] = vert4;
177 verts[idx5] = vert5;
178 verts[idx6] = vert6;
179
180 glyphIdx++;
181 }
182
183 // Offset for carriage return character that still generates verts
184 glyphIdx++;
185 }
186 vh.Clear();
187 vh.AddUIVertexTriangleStream(verts);
188 }
189 }
190}
UnityEngine.Debug Debug
Definition: TanodaServer.cs:19
override void ModifyMesh(VertexHelper vh)
Definition: MonoSpacing.cs:95
Credit Erdener Gonenc - @PixelEnvision.