├── .gitattributes
├── .gitignore
├── AdvancedComponent.meta
├── AdvancedComponent
├── AdvancedImage.cs
├── AdvancedImage.cs.meta
├── AdvancedText.cs
├── AdvancedText.cs.meta
├── Editor.meta
├── Editor
│ ├── AdvancedImageEditor.cs
│ ├── AdvancedImageEditor.cs.meta
│ ├── AdvancedTextEditor.cs
│ └── AdvancedTextEditor.cs.meta
├── ShaderOutLine.cs
├── ShaderOutLine.cs.meta
├── UI-OutLine.mat
├── UI-OutLine.mat.meta
├── UI-OutLine.shader
└── UI-OutLine.shader.meta
├── AutoCreateImage.meta
├── AutoCreateImage
├── Editor.meta
└── Editor
│ ├── AutoCreateImage.cs
│ └── AutoCreateImage.cs.meta
├── LICENSE
├── LICENSE.meta
├── PrefabLoader.meta
├── PrefabLoader
├── PrefabLoader.cs
└── PrefabLoader.cs.meta
├── README.md
├── README.md.meta
├── UI3DModifier.meta
├── UI3DModifier
├── UI-3DModifier.shader
├── UI-3DModifier.shader.meta
├── UI3DModifier.cs
└── UI3DModifier.cs.meta
├── UIBake.meta
├── UIBake
├── Editor.meta
├── Editor
│ ├── UIMeshBakeEditor.cs
│ └── UIMeshBakeEditor.cs.meta
├── UIBakeMesh.cs
├── UIBakeMesh.cs.meta
├── UIBakeMeshAsset.cs
├── UIBakeMeshAsset.cs.meta
├── UIBakeMeshCreater.cs
└── UIBakeMeshCreater.cs.meta
├── UIEffect.meta
├── UIEffect
├── Particle Add Clip.shader
├── Particle Add Clip.shader.meta
├── Particle Alpha Blend Clip.shader
├── Particle Alpha Blend Clip.shader.meta
├── Particles_Alpha Blended (Clip).mat
├── Particles_Alpha Blended (Clip).mat.meta
├── UIClipAble.cs
└── UIClipAble.cs.meta
├── UILineFeedFixed
└── LineFeedFixed.cs
├── UIPSDViewer.meta
├── UIPSDViewer
├── Plugins.meta
├── Plugins
│ ├── PsdParser.dll
│ └── PsdParser.dll.meta
├── TestFile.psd
├── TestFile.psd.meta
├── UIPSDViewer.cs
└── UIPSDViewer.cs.meta
├── UIPackage.meta
└── UIPackage
├── Editor.meta
├── Editor
├── UIPackageEditor.cs
└── UIPackageEditor.cs.meta
├── UIPackage.cs
└── UIPackage.cs.meta
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /[Ll]ibrary/
2 | /[Tt]emp/
3 | /[Oo]bj/
4 | /[Bb]uild/
5 | /[Bb]uilds/
6 | /Assets/AssetStoreTools*
7 |
8 | # Visual Studio 2015 cache directory
9 | /.vs/
10 |
11 | # Autogenerated VS/MD/Consulo solution and project files
12 | ExportedObj/
13 | .consulo/
14 | *.csproj
15 | *.unityproj
16 | *.sln
17 | *.suo
18 | *.tmp
19 | *.user
20 | *.userprefs
21 | *.pidb
22 | *.booproj
23 | *.svd
24 | *.pdb
25 |
26 | # Unity3D generated meta files
27 | *.pidb.meta
28 |
29 | # Unity3D Generated File On Crash Reports
30 | sysinfo.txt
31 |
32 | # Builds
33 | *.apk
34 | *.unitypackage
35 |
--------------------------------------------------------------------------------
/AdvancedComponent.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e9ce451f4dcd61b429a47c49393866d1
3 | folderAsset: yes
4 | timeCreated: 1516557995
5 | licenseType: Pro
6 | DefaultImporter:
7 | externalObjects: {}
8 | userData:
9 | assetBundleName:
10 | assetBundleVariant:
11 |
--------------------------------------------------------------------------------
/AdvancedComponent/AdvancedImage.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 | using UnityEngine.UI;
5 |
6 | namespace UGUIExtend
7 | {
8 | [RequireComponent(typeof(RectTransform))]
9 | [RequireComponent(typeof(CanvasRenderer))]
10 | [AddComponentMenu("UI/AdvancedImage", 12)]
11 | public class AdvancedImage : Image
12 | {
13 | ///
14 | /// 可见度
15 | ///
16 | [SerializeField]
17 | private bool m_Visible = true;
18 | public bool visible
19 | {
20 | get
21 | {
22 | return m_Visible;
23 |
24 | }
25 |
26 | set
27 | {
28 | if (m_Visible != value)
29 | {
30 | m_Visible = value;
31 | UpdateVisible();
32 | if (m_Visible)
33 | CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);
34 | }
35 | }
36 | }
37 |
38 | ///
39 | /// 是否绘制
40 | ///
41 | [SerializeField]
42 | private bool m_EnabledPopulateMesh = true;
43 | public bool enabledPopulateMesh
44 | {
45 | get
46 | {
47 | return m_EnabledPopulateMesh;
48 | }
49 |
50 | set
51 | {
52 | if (m_EnabledPopulateMesh != value)
53 | {
54 | SetVerticesDirty();
55 | }
56 | m_EnabledPopulateMesh = value;
57 | }
58 | }
59 |
60 | ///
61 | /// 是否使用Sprite的网格
62 | ///
63 | [SerializeField]
64 | private bool m_UseSpriteMesh;
65 | public bool useSpriteMesh
66 | {
67 | get
68 | {
69 | return m_UseSpriteMesh;
70 | }
71 |
72 | set
73 | {
74 | if (m_UseSpriteMesh != value)
75 | {
76 | SetVerticesDirty();
77 | }
78 | m_UseSpriteMesh = value;
79 | }
80 | }
81 |
82 | ///
83 | /// 水平镜像
84 | ///
85 | [SerializeField]
86 | private bool m_HorizontalMirror;
87 | public bool horizontalMirror
88 | {
89 | get
90 | {
91 | return m_HorizontalMirror;
92 | }
93 |
94 | set
95 | {
96 | if (m_UseSpriteMesh != value)
97 | {
98 | SetVerticesDirty();
99 | }
100 | m_HorizontalMirror = value;
101 | }
102 | }
103 |
104 | ///
105 | /// 垂直镜像
106 | ///
107 | [SerializeField]
108 | private bool m_VerticalMirror;
109 | public bool verticalMirror
110 | {
111 | get
112 | {
113 | return m_VerticalMirror;
114 | }
115 |
116 | set
117 | {
118 | if (m_VerticalMirror != value)
119 | {
120 | SetVerticesDirty();
121 | }
122 | m_VerticalMirror = value;
123 | }
124 | }
125 |
126 | ///
127 | /// 设置中间挖空部分的边缘,FillCenter激活时无效
128 | ///
129 | [SerializeField]
130 | private Vector4 m_FillBorders = Vector4.zero;
131 | public Vector4 fillBorders
132 | {
133 | get
134 | {
135 | return m_FillBorders;
136 | }
137 |
138 | set
139 | {
140 | if (m_FillBorders != value)
141 | {
142 | SetVerticesDirty();
143 | }
144 | m_FillBorders = value;
145 | }
146 |
147 |
148 | }
149 |
150 |
151 | ///
152 | /// 碰撞箱
153 | ///
154 | [SerializeField]
155 | public Collider2D hitArea;
156 |
157 | ///
158 | /// 使用Sprite网格作为碰撞箱
159 | ///
160 | [SerializeField]
161 | public bool useSpriteHitArea;
162 |
163 | ///
164 | /// 碰撞箱缩放
165 | ///
166 | [SerializeField]
167 | public Vector2 hitScale = Vector2.one;
168 |
169 | protected override void OnEnable()
170 | {
171 | base.OnEnable();
172 | UpdateVisible();
173 | }
174 |
175 | protected virtual void UpdateVisible()
176 | {
177 | this.canvasRenderer.cull = !m_Visible;
178 | }
179 |
180 | public override bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera)
181 | {
182 | if (!useSpriteHitArea && hitArea == null && hitScale == Vector2.one)
183 | {
184 | return base.IsRaycastLocationValid(screenPoint, eventCamera);
185 | }
186 |
187 | if (eventCamera != null)
188 | {
189 | screenPoint = eventCamera.ScreenToWorldPoint(screenPoint);
190 | }
191 | if (hitScale != Vector2.one)
192 | {
193 | Vector2 centerInScreen = transform.position;
194 | screenPoint = centerInScreen + Vector2.Scale(screenPoint - centerInScreen, new Vector2(1f / hitScale.x, 1f / hitScale.y));
195 | }
196 | if (useSpriteHitArea && IsRaycastSprite(rectTransform.InverseTransformPoint(screenPoint)) ||
197 | hitArea != null && hitArea.OverlapPoint(screenPoint) ||
198 | !useSpriteHitArea && hitArea == null && rectTransform.rect.Contains(rectTransform.InverseTransformPoint(screenPoint)))
199 | {
200 | return true;
201 | }
202 | return false;
203 | }
204 |
205 | bool IsRaycastSprite(Vector2 point)
206 | {
207 | Rect r = GetPixelAdjustedRect();
208 | var size = new Vector2(overrideSprite.rect.width, overrideSprite.rect.height);
209 | Bounds bounds = overrideSprite.bounds;
210 |
211 | if (preserveAspect)
212 | {
213 | PreserveAspect(ref r, size);
214 | }
215 |
216 | float w = r.width / bounds.size.x;
217 | float h = r.height / bounds.size.y;
218 | point.x = (point.x + w * bounds.center.x) / w;
219 | point.y = (point.y + h * bounds.center.y) / h;
220 |
221 | var vertices = overrideSprite.vertices;
222 | var triangles = overrideSprite.triangles;
223 | int count = triangles.Length;
224 | for (int i = 0;i < count;i+= 3)
225 | {
226 | Vector2 v1 = vertices[triangles[i]];
227 | Vector2 v2 = vertices[triangles[i + 1]];
228 | Vector2 v3 = vertices[triangles[i + 2]];
229 | if (PointinTriangle(v1, v2, v3, point))
230 | return true;
231 | }
232 | return false;
233 | }
234 |
235 | // 三角形碰撞检测
236 | static bool PointinTriangle(Vector2 A, Vector2 B, Vector2 C, Vector2 P)
237 | {
238 | Vector2 v0 = C - A;
239 | Vector2 v1 = B - A;
240 | Vector2 v2 = P - A;
241 |
242 | float dot00 = Vector2.Dot(v0, v0);
243 | float dot01 = Vector2.Dot(v0, v1);
244 | float dot02 = Vector2.Dot(v0, v2);
245 | float dot11 = Vector2.Dot(v1, v1);
246 | float dot12 = Vector2.Dot(v1, v2);
247 |
248 | float inverDeno = 1 / (dot00 * dot11 - dot01 * dot01);
249 |
250 | float u = (dot11 * dot02 - dot01 * dot12) * inverDeno;
251 | if (u < 0 || u > 1)
252 | {
253 | return false;
254 | }
255 |
256 | float v = (dot00 * dot12 - dot01 * dot02) * inverDeno;
257 | if (v < 0 || v > 1)
258 | {
259 | return false;
260 | }
261 |
262 | return u + v <= 1;
263 | }
264 |
265 | protected override void OnPopulateMesh(VertexHelper toFill)
266 | {
267 | if (!m_EnabledPopulateMesh)
268 | {
269 | toFill.Clear();
270 | return;
271 | }
272 |
273 | if (overrideSprite == null)
274 | {
275 | base.OnPopulateMesh(toFill);
276 | return;
277 | }
278 |
279 | switch (type)
280 | {
281 | case Type.Simple:
282 | if (m_UseSpriteMesh)
283 | GenerateSpriteSprite(toFill, preserveAspect);
284 | else
285 | GenerateSimpleSprite(toFill, preserveAspect);
286 | break;
287 | case Type.Sliced:
288 | GenerateSlicedSprite(toFill);
289 | break;
290 | default:
291 | base.OnPopulateMesh(toFill);
292 | break;
293 | }
294 | }
295 |
296 | public override void SetNativeSize()
297 | {
298 | if (overrideSprite != null && (type == Type.Simple || type == Type.Sliced) && (m_HorizontalMirror || m_VerticalMirror))
299 | {
300 | float w = overrideSprite.rect.width / pixelsPerUnit;
301 | float h = overrideSprite.rect.height / pixelsPerUnit;
302 | rectTransform.anchorMax = rectTransform.anchorMin;
303 |
304 | if (m_HorizontalMirror && m_VerticalMirror)
305 | {
306 | rectTransform.sizeDelta = new Vector2(w * 2, h * 2);
307 | }
308 | else if (m_HorizontalMirror)
309 | {
310 | rectTransform.sizeDelta = new Vector2(w * 2, h);
311 | }
312 | else
313 | {
314 | rectTransform.sizeDelta = new Vector2(w, h * 2);
315 | }
316 | }
317 | else
318 | {
319 | base.SetNativeSize();
320 | }
321 | }
322 |
323 | ///
324 | /// 用Sprite的网格数据直接创建顶点
325 | ///
326 | void GenerateSpriteSprite(VertexHelper vh, bool shouldPreserveAspect)
327 | {
328 | Rect r = GetPixelAdjustedRect();
329 | var size = new Vector2(overrideSprite.rect.width, overrideSprite.rect.height);
330 | Bounds bounds = overrideSprite.bounds;
331 |
332 | if (shouldPreserveAspect)
333 | {
334 | PreserveAspect(ref r, size);
335 | }
336 |
337 | float w = r.width / bounds.size.x;
338 | float h = r.height / bounds.size.y;
339 | Vector4 v = new Vector4(-w * bounds.center.x,
340 | -h * bounds.center.y,
341 | w,
342 | h);
343 |
344 | Color32 color32 = color;
345 | vh.Clear();
346 | var vertices = overrideSprite.vertices;
347 | var uv = overrideSprite.uv;
348 | int count = vertices.Length;
349 | for (int i = 0; i < count; i++)
350 | {
351 | Vector2 vert = vertices[i];
352 | vh.AddVert(new Vector3(v.x + vert.x * v.z, v.y + vert.y * v.w, 0), color32, uv[i]);
353 | }
354 | var triangles = overrideSprite.triangles;
355 | count = triangles.Length;
356 | for (int i = 0; i < count; i += 3)
357 | {
358 | vh.AddTriangle(triangles[i], triangles[i + 1], triangles[i + 2]);
359 | }
360 | }
361 |
362 |
363 |
364 | ///
365 | /// Generate vertices for a simple Image.
366 | ///
367 | void GenerateSimpleSprite(VertexHelper vh, bool shouldPreserveAspect)
368 | {
369 | Vector4 v = GetDrawingDimensions(shouldPreserveAspect);
370 | var uv = (overrideSprite != null) ? UnityEngine.Sprites.DataUtility.GetOuterUV(overrideSprite) : Vector4.zero;
371 |
372 | var color32 = color;
373 | vh.Clear();
374 |
375 | if (!fillCenter)
376 | {
377 | if (m_FillBorders != Vector4.zero)
378 | {
379 | AddBorders(vh,
380 | v,
381 | m_FillBorders, color,
382 | uv);
383 | }
384 | }
385 | else
386 | {
387 | if (!m_HorizontalMirror && !m_VerticalMirror)
388 | {
389 | vh.AddVert(new Vector3(v.x, v.y), color32, new Vector2(uv.x, uv.y));
390 | vh.AddVert(new Vector3(v.x, v.w), color32, new Vector2(uv.x, uv.w));
391 | vh.AddVert(new Vector3(v.z, v.w), color32, new Vector2(uv.z, uv.w));
392 | vh.AddVert(new Vector3(v.z, v.y), color32, new Vector2(uv.z, uv.y));
393 |
394 | vh.AddTriangle(0, 1, 2);
395 | vh.AddTriangle(2, 3, 0);
396 | }
397 | else
398 | {
399 | AddMirror(vh, v, color32, uv, m_HorizontalMirror, m_VerticalMirror);
400 | }
401 | }
402 | }
403 |
404 | ///
405 | /// Generate vertices for a 9-sliced Image.
406 | ///
407 |
408 | static readonly Vector2[] s_VertScratch = new Vector2[4];
409 | static readonly Vector2[] s_UVScratch = new Vector2[4];
410 |
411 | private void GenerateSlicedSprite(VertexHelper toFill)
412 | {
413 | if (!hasBorder)
414 | {
415 | GenerateSimpleSprite(toFill, false);
416 | return;
417 | }
418 |
419 | Vector4 outer, inner, padding, border;
420 |
421 | if (overrideSprite != null)
422 | {
423 | outer = UnityEngine.Sprites.DataUtility.GetOuterUV(overrideSprite);
424 | inner = UnityEngine.Sprites.DataUtility.GetInnerUV(overrideSprite);
425 | padding = UnityEngine.Sprites.DataUtility.GetPadding(overrideSprite);
426 | border = overrideSprite.border;
427 | }
428 | else
429 | {
430 | outer = Vector4.zero;
431 | inner = Vector4.zero;
432 | padding = Vector4.zero;
433 | border = Vector4.zero;
434 | }
435 |
436 | Rect rect = GetPixelAdjustedRect();
437 | Vector4 adjustedBorders = GetAdjustedBorders(border / pixelsPerUnit, rect);
438 | padding = padding / pixelsPerUnit;
439 | if (m_HorizontalMirror)
440 | {
441 | adjustedBorders.z = adjustedBorders.x;
442 | }
443 | if (m_VerticalMirror)
444 | {
445 | adjustedBorders.y = adjustedBorders.w;
446 | }
447 |
448 | s_VertScratch[0] = new Vector2(padding.x, padding.y);
449 | s_VertScratch[3] = new Vector2(rect.width - padding.z, rect.height - padding.w);
450 |
451 | s_VertScratch[1].x = adjustedBorders.x;
452 | s_VertScratch[1].y = adjustedBorders.y;
453 |
454 | s_VertScratch[2].x = rect.width - adjustedBorders.z;
455 | s_VertScratch[2].y = rect.height - adjustedBorders.w;
456 |
457 | for (int i = 0; i < 4; ++i)
458 | {
459 | s_VertScratch[i].x += rect.x;
460 | s_VertScratch[i].y += rect.y;
461 | }
462 |
463 | s_UVScratch[0] = new Vector2(outer.x, outer.y);
464 | s_UVScratch[1] = new Vector2(inner.x, inner.y);
465 | s_UVScratch[2] = new Vector2(inner.z, inner.w);
466 | s_UVScratch[3] = new Vector2(outer.z, outer.w);
467 |
468 | toFill.Clear();
469 |
470 | for (int x = 0; x < 3; ++x)
471 | {
472 | int x2 = x + 1;
473 |
474 | for (int y = 0; y < 3; ++y)
475 | {
476 | int y2 = y + 1;
477 |
478 | if (!fillCenter && x == 1 && y == 1)
479 | {
480 | if (m_FillBorders != Vector4.zero)
481 | {
482 | AddBorders(toFill,
483 | new Vector4(s_VertScratch[x].x, s_VertScratch[y].y, s_VertScratch[x2].x, s_VertScratch[y2].y),
484 | m_FillBorders, color,
485 | new Vector4(s_UVScratch[x].x, s_UVScratch[y].y, s_UVScratch[x2].x, s_UVScratch[y2].y));
486 | }
487 | continue;
488 | }
489 |
490 | Vector4 uv;
491 | if (x == 2 && y == 0 && m_HorizontalMirror && m_VerticalMirror)
492 | {
493 | uv = new Vector4(s_UVScratch[1].x, s_UVScratch[3].y, s_UVScratch[0].x, s_UVScratch[2].y);
494 | }
495 | else if (x == 2 && m_HorizontalMirror)
496 | {
497 | uv = new Vector4(s_UVScratch[1].x, s_UVScratch[y].y, s_UVScratch[0].x, s_UVScratch[y2].y);
498 | }
499 | else if (y == 0 && m_VerticalMirror)
500 | {
501 | uv = new Vector4(s_UVScratch[x].x, s_UVScratch[3].y, s_UVScratch[x2].x, s_UVScratch[2].y);
502 | }
503 | else
504 | {
505 | uv = new Vector4(s_UVScratch[x].x, s_UVScratch[y].y, s_UVScratch[x2].x, s_UVScratch[y2].y);
506 | }
507 |
508 | AddMirror(toFill,
509 | new Vector4(s_VertScratch[x].x, s_VertScratch[y].y,s_VertScratch[x2].x, s_VertScratch[y2].y),
510 | color,
511 | uv,
512 | m_HorizontalMirror && x == 1, m_VerticalMirror && y == 1);
513 | }
514 | }
515 | }
516 |
517 | static void AddMirror(VertexHelper vh, Vector4 v, Color32 color32, Vector4 uv, bool hMirror, bool vMirror)
518 | {
519 | if (v.x >= v.z || v.y >= v.w)
520 | {
521 | return;
522 | }
523 | int si = vh.currentVertCount;
524 |
525 | if (hMirror && vMirror)
526 | {
527 | float d = (v.z - v.x) / 2f;
528 | v.z -= d;
529 | float d2 = (v.w - v.y) / 2f;
530 | v.y += d2;
531 | vh.AddVert(new Vector3(v.x, v.y), color32, new Vector2(uv.x, uv.y));
532 | vh.AddVert(new Vector3(v.x, v.w), color32, new Vector2(uv.x, uv.w));
533 | vh.AddVert(new Vector3(v.z, v.w), color32, new Vector2(uv.z, uv.w));
534 | vh.AddVert(new Vector3(v.z, v.y), color32, new Vector2(uv.z, uv.y));
535 |
536 | vh.AddVert(new Vector3(v.z + d, v.w), color32, new Vector2(uv.x, uv.w));
537 | vh.AddVert(new Vector3(v.z + d, v.y), color32, new Vector2(uv.x, uv.y));
538 |
539 | vh.AddVert(new Vector3(v.x, v.y - d2), color32, new Vector2(uv.x, uv.w));
540 | vh.AddVert(new Vector3(v.z, v.y - d2), color32, new Vector2(uv.z, uv.w));
541 | vh.AddVert(new Vector3(v.z + d, v.y - d2), color32, new Vector2(uv.x, uv.w));
542 |
543 | vh.AddTriangle(si, si + 1, si + 2);
544 | vh.AddTriangle(si + 2, si + 3, si);
545 | vh.AddTriangle(si + 3, si + 2, si + 5);
546 | vh.AddTriangle(si + 5, si + 2, si + 4);
547 | vh.AddTriangle(si, si + 3, si + 7);
548 | vh.AddTriangle(si, si + 7, si + 6);
549 | vh.AddTriangle(si + 3, si + 5, si + 7);
550 | vh.AddTriangle(si + 5, si + 8, si + 7);
551 | }
552 | else if (hMirror)
553 | {
554 | float d = (v.z - v.x) / 2f;
555 | v.z -= d;
556 | vh.AddVert(new Vector3(v.x, v.y), color32, new Vector2(uv.x, uv.y));
557 | vh.AddVert(new Vector3(v.x, v.w), color32, new Vector2(uv.x, uv.w));
558 | vh.AddVert(new Vector3(v.z, v.w), color32, new Vector2(uv.z, uv.w));
559 | vh.AddVert(new Vector3(v.z, v.y), color32, new Vector2(uv.z, uv.y));
560 |
561 | vh.AddVert(new Vector3(v.z + d, v.w), color32, new Vector2(uv.x, uv.w));
562 | vh.AddVert(new Vector3(v.z + d, v.y), color32, new Vector2(uv.x, uv.y));
563 |
564 | vh.AddTriangle(si, si + 1, si + 2);
565 | vh.AddTriangle(si + 2, si + 3, si);
566 | vh.AddTriangle(si + 3, si + 2, si + 5);
567 | vh.AddTriangle(si + 5, si + 2, si + 4);
568 | }
569 | else if (vMirror)
570 | {
571 | float d = (v.w - v.y) / 2f;
572 | v.y += d;
573 | vh.AddVert(new Vector3(v.x, v.y), color32, new Vector2(uv.x, uv.y));
574 | vh.AddVert(new Vector3(v.x, v.w), color32, new Vector2(uv.x, uv.w));
575 | vh.AddVert(new Vector3(v.z, v.w), color32, new Vector2(uv.z, uv.w));
576 | vh.AddVert(new Vector3(v.z, v.y), color32, new Vector2(uv.z, uv.y));
577 |
578 | vh.AddVert(new Vector3(v.x, v.y - d), color32, new Vector2(uv.x, uv.w));
579 | vh.AddVert(new Vector3(v.z, v.y - d), color32, new Vector2(uv.z, uv.w));
580 |
581 | vh.AddTriangle(si, si + 1, si + 2);
582 | vh.AddTriangle(si + 2, si + 3, si);
583 | vh.AddTriangle(si, si + 3, si + 5);
584 | vh.AddTriangle(si, si + 5, si + 4);
585 | }
586 | else
587 | {
588 | vh.AddVert(new Vector3(v.x, v.y), color32, new Vector2(uv.x, uv.y));
589 | vh.AddVert(new Vector3(v.x, v.w), color32, new Vector2(uv.x, uv.w));
590 | vh.AddVert(new Vector3(v.z, v.w), color32, new Vector2(uv.z, uv.w));
591 | vh.AddVert(new Vector3(v.z, v.y), color32, new Vector2(uv.z, uv.y));
592 |
593 | vh.AddTriangle(si, si + 1, si + 2);
594 | vh.AddTriangle(si + 2, si + 3, si);
595 | }
596 | }
597 |
598 | static void AddBorders(VertexHelper vertexHelper, Vector4 pos, Vector4 border,Color32 color, Vector4 uv)
599 | {
600 | float w = pos.z - pos.x;
601 | float h = pos.w - pos.y;
602 | float uvW = uv.z - uv.x;
603 | float uvH = uv.w - uv.y;
604 | Vector4 inner = new Vector4(pos.x + w * border.x,
605 | pos.y + h * border.y,
606 | pos.z - w * border.z,
607 | pos.w - h * border.w);
608 |
609 | Vector4 innerUv = new Vector4(uv.x + uvW * border.x,
610 | uv.y + uvH * border.y,
611 | uv.z - uvW * border.z,
612 | uv.w - uvH * border.w);
613 |
614 | if (border.y > 0)
615 | AddQuad(vertexHelper, new Vector4(pos.x, pos.y, pos.z, inner.y), color, new Vector4(uv.x, uv.y, uv.z, innerUv.y));
616 | if (border.w > 0)
617 | AddQuad(vertexHelper, new Vector4(pos.x, inner.w, pos.z, pos.w), color, new Vector4(uv.x, innerUv.w, uv.z, uv.w));
618 | if (border.x > 0)
619 | AddQuad(vertexHelper, new Vector4(pos.x, inner.y, inner.x, inner.w), color, new Vector4(uv.x, innerUv.y, innerUv.x, innerUv.w));
620 | if (border.z > 0)
621 | AddQuad(vertexHelper, new Vector4(inner.z, inner.y, pos.z, inner.w), color, new Vector4(innerUv.z, innerUv.y, uv.z, innerUv.w));
622 | }
623 |
624 | static void AddQuad(VertexHelper vertexHelper, Vector4 pos, Color32 color, Vector4 uv)
625 | {
626 | int startIndex = vertexHelper.currentVertCount;
627 |
628 | vertexHelper.AddVert(new Vector3(pos.x, pos.y, 0), color, new Vector2(uv.x, uv.y));
629 | vertexHelper.AddVert(new Vector3(pos.x, pos.w, 0), color, new Vector2(uv.x, uv.w));
630 | vertexHelper.AddVert(new Vector3(pos.z, pos.w, 0), color, new Vector2(uv.z, uv.w));
631 | vertexHelper.AddVert(new Vector3(pos.z, pos.y, 0), color, new Vector2(uv.z, uv.y));
632 |
633 | vertexHelper.AddTriangle(startIndex, startIndex + 1, startIndex + 2);
634 | vertexHelper.AddTriangle(startIndex + 2, startIndex + 3, startIndex);
635 | }
636 |
637 | Vector4 GetAdjustedBorders(Vector4 border, Rect rect)
638 | {
639 | for (int axis = 0; axis <= 1; axis++)
640 | {
641 | // If the rect is smaller than the combined borders, then there's not room for the borders at their normal size.
642 | // In order to avoid artefacts with overlapping borders, we scale the borders down to fit.
643 | float combinedBorders = border[axis] + border[axis + 2];
644 | if (rect.size[axis] < combinedBorders && combinedBorders != 0)
645 | {
646 | float borderScaleRatio = rect.size[axis] / combinedBorders;
647 | border[axis] *= borderScaleRatio;
648 | border[axis + 2] *= borderScaleRatio;
649 | }
650 | }
651 | return border;
652 | }
653 |
654 |
655 | /// Image's dimensions used for drawing. X = left, Y = bottom, Z = right, W = top.
656 | private Vector4 GetDrawingDimensions(bool shouldPreserveAspect)
657 | {
658 | Rect r = GetPixelAdjustedRect();
659 |
660 | var size = overrideSprite == null ? Vector2.zero : new Vector2(overrideSprite.rect.width, overrideSprite.rect.height);
661 | var padding = overrideSprite == null ? Vector4.zero : UnityEngine.Sprites.DataUtility.GetPadding(overrideSprite);
662 | int spriteW = Mathf.RoundToInt(size.x);
663 | int spriteH = Mathf.RoundToInt(size.y);
664 |
665 | Vector4 v = new Vector4(
666 | padding.x / spriteW,
667 | padding.y / spriteH,
668 | (spriteW - padding.z) / spriteW,
669 | (spriteH - padding.w) / spriteH);
670 |
671 | if (shouldPreserveAspect)
672 | {
673 | PreserveAspect(ref r, size);
674 | }
675 |
676 | v = new Vector4(
677 | r.x + r.width * v.x,
678 | r.y + r.height * v.y,
679 | r.x + r.width * v.z,
680 | r.y + r.height * v.w
681 | );
682 |
683 | return v;
684 | }
685 |
686 | private void PreserveAspect(ref Rect r,Vector2 size)
687 | {
688 | if (size.sqrMagnitude == 0.0f)
689 | return;
690 |
691 | var spriteRatio = size.x / size.y;
692 | var rectRatio = r.width / r.height;
693 |
694 | if (spriteRatio > rectRatio)
695 | {
696 | var oldHeight = r.height;
697 | r.height = r.width * (1.0f / spriteRatio);
698 | r.y += (oldHeight - r.height) * rectTransform.pivot.y;
699 | }
700 | else
701 | {
702 | var oldWidth = r.width;
703 | r.width = r.height * spriteRatio;
704 | r.x += (oldWidth - r.width) * rectTransform.pivot.x;
705 | }
706 | }
707 |
708 | #if UNITY_EDITOR
709 | protected override void OnValidate()
710 | {
711 | base.OnValidate();
712 | UpdateVisible();
713 | }
714 |
715 | private readonly static Vector3[] fourCorners = new Vector3[4];
716 | private void OnDrawGizmosSelected()
717 | {
718 | if (this.raycastTarget)
719 | {
720 | Gizmos.color = Color.green;
721 |
722 | if (this.useSpriteHitArea)
723 | {
724 | Rect r = GetPixelAdjustedRect();
725 | var size = new Vector2(overrideSprite.rect.width, overrideSprite.rect.height);
726 | Bounds bounds = overrideSprite.bounds;
727 |
728 | if (preserveAspect)
729 | {
730 | PreserveAspect(ref r, size);
731 | }
732 |
733 | float w = r.width / bounds.size.x;
734 | float h = r.height / bounds.size.y;
735 | Vector4 v = new Vector4(-w * bounds.center.x,
736 | -h * bounds.center.y,
737 | w,
738 | h);
739 | int count = overrideSprite.triangles.Length;
740 | var vertices = overrideSprite.vertices;
741 | var triangles = overrideSprite.triangles;
742 | Vector2 center = transform.position;
743 | for (int i = 0; i < count; i += 3)
744 | {
745 | Vector2 v1 = vertices[triangles[i]];
746 | Vector2 v2 = vertices[triangles[i + 1]];
747 | Vector2 v3 = vertices[triangles[i + 2]];
748 | v1 = transform.TransformPoint(new Vector2(v.x + v1.x * v.z, v.y + v1.y * v.w));
749 | v2 = transform.TransformPoint(new Vector2(v.x + v2.x * v.z, v.y + v2.y * v.w));
750 | v3 = transform.TransformPoint(new Vector2(v.x + v3.x * v.z, v.y + v3.y * v.w));
751 | v1 = transform.position + Vector3.Scale(v1 - center, hitScale);
752 | v2 = transform.position + Vector3.Scale(v2 - center, hitScale);
753 | v3 = transform.position + Vector3.Scale(v3 - center, hitScale);
754 | Gizmos.DrawLine(v1, v2);
755 | Gizmos.DrawLine(v2, v3);
756 | Gizmos.DrawLine(v3, v1);
757 | }
758 | }
759 | else
760 | {
761 | rectTransform.GetWorldCorners(fourCorners);
762 | for (int i = 0; i < 4; i++)
763 | {
764 | fourCorners[i] = transform.position + Vector3.Scale(fourCorners[i] - transform.position,hitScale);
765 | }
766 | for (int i = 0; i < 4; i++)
767 | {
768 | Gizmos.DrawLine(fourCorners[i], fourCorners[(i + 1) % 4]);
769 | }
770 | }
771 | }
772 | }
773 | #endif
774 | }
775 | }
776 |
777 |
778 |
779 |
--------------------------------------------------------------------------------
/AdvancedComponent/AdvancedImage.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: bee77fc9eb05d584590e222fbd6efa70
3 | timeCreated: 1509015394
4 | licenseType: Free
5 | MonoImporter:
6 | externalObjects: {}
7 | serializedVersion: 2
8 | defaultReferences: []
9 | executionOrder: 0
10 | icon: {instanceID: 0}
11 | userData:
12 | assetBundleName:
13 | assetBundleVariant:
14 |
--------------------------------------------------------------------------------
/AdvancedComponent/AdvancedText.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 | using UnityEngine.UI;
5 | using System.Text.RegularExpressions;
6 | using UnityEngine.Serialization;
7 | using System;
8 |
9 | namespace UGUIExtend
10 | {
11 | [RequireComponent(typeof(RectTransform))]
12 | [RequireComponent(typeof(CanvasRenderer))]
13 | [AddComponentMenu("UI/AdvancedText", 12)]
14 | public class AdvancedText : Text
15 | {
16 | ///
17 | /// 加载图片的方法
18 | ///
19 | protected virtual void LoadSprite(Image image, string path)
20 | {
21 | if (image.sprite == null || image.sprite.name != path)
22 | {
23 | image.sprite = Resources.Load(imagePathRoot + path); ;
24 | }
25 | }
26 |
27 | [Serializable]
28 | public class CharOffest
29 | {
30 | public Vector2 position = Vector2.zero;
31 | public float rotation = 0f;
32 | public Vector2 scale = Vector2.one;
33 | }
34 |
35 | [Serializable]
36 | public class InLineImage
37 | {
38 | public bool cull;
39 | public Image image;
40 | public InLineImage(Image image)
41 | {
42 | this.image = image;
43 | this.cull = false;
44 | }
45 | }
46 |
47 | private static readonly Regex s_Regex = new Regex(@"", RegexOptions.Singleline);
48 | ///
49 | /// 可见度
50 | ///
51 | [SerializeField]
52 | private bool m_Visible = true;
53 | public bool visible
54 | {
55 | get { return m_Visible; }
56 | set
57 | {
58 | if (m_Visible != value)
59 | {
60 | m_Visible = value;
61 | UpdateVisible();
62 | if (m_Visible)
63 | CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);
64 | }
65 | }
66 | }
67 |
68 | ///
69 | /// 外部图片加载目录
70 | ///
71 | [SerializeField]
72 | public string imagePathRoot = "";
73 |
74 | public enum TextEffectType
75 | {
76 | NONE,
77 | SHADOW,
78 | OUTLINE4,
79 | OUTLINE8,
80 | MATERIAL
81 | }
82 |
83 | ///
84 | /// 文字描边类型
85 | ///
86 | [SerializeField]
87 | private TextEffectType m_EffectType = TextEffectType.NONE;
88 | public TextEffectType effectType
89 | {
90 | get { return m_EffectType; }
91 | set
92 | {
93 | if (m_EffectType != value)
94 | {
95 | m_EffectType = value;
96 | SetVerticesDirty();
97 | }
98 | }
99 | }
100 |
101 | ///
102 | /// 文字描边颜色
103 | ///
104 | [SerializeField]
105 | private Color32 m_EffectColor = new Color(0, 0, 0, 128);
106 | public Color32 effectColor
107 | {
108 | get { return m_EffectColor; }
109 | set
110 | {
111 | if (!Equals(m_EffectColor, value))
112 | {
113 | m_EffectColor = value;
114 | SetVerticesDirty();
115 | }
116 | }
117 | }
118 |
119 | ///
120 | /// 文字描边宽度
121 | ///
122 | [SerializeField]
123 | private Vector2 m_EffectDistance = new Vector2(1f, -1f);
124 | public Vector2 effectDistance
125 | {
126 | get { return m_EffectDistance; }
127 | set
128 | {
129 | if (m_EffectDistance != value)
130 | {
131 | m_EffectDistance = value;
132 | SetVerticesDirty();
133 | }
134 | }
135 | }
136 |
137 | ///
138 | /// 是否混合描边透明度(取消可增加性能)
139 | ///
140 | [SerializeField]
141 | private bool m_UseGraphicAlpha = false;
142 | public bool useGraphicAlpha
143 | {
144 | get { return m_UseGraphicAlpha; }
145 | set
146 | {
147 | if (m_UseGraphicAlpha != value)
148 | {
149 | m_UseGraphicAlpha = value;
150 | SetVerticesDirty();
151 | }
152 | }
153 | }
154 | [SerializeField]
155 | private bool m_EnabledGradient = false;
156 | public bool enabledGradient
157 | {
158 | get { return m_EnabledGradient; }
159 | set
160 | {
161 | if (m_EnabledGradient != value)
162 | {
163 | m_EnabledGradient = value;
164 | SetVerticesDirty();
165 | }
166 | }
167 | }
168 | [SerializeField]
169 | private Color m_GradientColor = Color.white;
170 | public Color gradientColor
171 | {
172 | get { return m_GradientColor; }
173 | set
174 | {
175 | if (m_GradientColor != value)
176 | {
177 | m_GradientColor = value;
178 | SetVerticesDirty();
179 | }
180 | }
181 | }
182 |
183 | ///
184 | /// 单字位移
185 | ///
186 | [SerializeField]
187 | public List charOffests;
188 |
189 | ///
190 | /// 设置单字位移
191 | ///
192 | public void SetCharOffest(int index, Vector3 position)
193 | {
194 | SeekToCharOffestIndex(index);
195 | this.charOffests[index].position = position;
196 | SetVerticesDirty();
197 | }
198 |
199 | public void SetCharOffest(int index, Vector3 position, float rotation)
200 | {
201 | SetCharOffest(index, position);
202 | this.charOffests[index].rotation = rotation;
203 | SetVerticesDirty();
204 | }
205 |
206 | public void SetCharOffest(int index, Vector3 position, float rotation, Vector3 scale)
207 | {
208 | SetCharOffest(index, position, rotation);
209 | this.charOffests[index].scale = scale;
210 | SetVerticesDirty();
211 | }
212 |
213 | private void SeekToCharOffestIndex(int index)
214 | {
215 | for (int i = charOffests.Count; i <= index; i++)
216 | this.charOffests.Add(null);
217 |
218 | if (this.charOffests[index] == null)
219 | this.charOffests[index] = new CharOffest();
220 | }
221 |
222 | protected override void OnEnable()
223 | {
224 | base.OnEnable();
225 | if (inlineImages != null)
226 | {
227 | int count = inlineImages.Count;
228 | for (int i = 0; i < count; i++)
229 | {
230 | if (inlineImages[i].image != null)
231 | inlineImages[i].image.enabled = true;
232 | }
233 | }
234 | UpdateVisible();
235 | }
236 |
237 | protected override void OnDisable()
238 | {
239 | base.OnDisable();
240 | if (inlineImages != null)
241 | {
242 | int count = inlineImages.Count;
243 | for (int i = 0; i < count; i++)
244 | {
245 | if (inlineImages[i].image != null)
246 | inlineImages[i].image.enabled = false;
247 | }
248 | }
249 | }
250 |
251 | protected virtual void UpdateVisible()
252 | {
253 | this.canvasRenderer.cull = !m_Visible;
254 | if (inlineImages != null)
255 | {
256 | int count = inlineImages.Count;
257 | for (int i = 0; i < count; i++)
258 | {
259 | InLineImage item = inlineImages[i];
260 | if (item.image != null)
261 | {
262 | bool cull = !m_Visible || item.cull;
263 | if (cull != item.image.canvasRenderer.cull)
264 | {
265 | item.image.canvasRenderer.cull = cull;
266 | if (!cull)
267 | {
268 | CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(item.image);//不加这个在隐藏状态时有变化不会更新
269 | }
270 | }
271 | }
272 | }
273 | }
274 | }
275 |
276 | ///
277 | /// 清除不使用的图片,释放内存
278 | ///
279 | public void ClearUnUsedInLineImage()
280 | {
281 | if (inlineImages != null)
282 | {
283 | int needCount = inlineCharIndex.Count;
284 | int count = inlineImages.Count;
285 | for (int i = count - 1; i > 0; i--)
286 | {
287 | InLineImage item = inlineImages[i];
288 | if (item.image != null && i >= needCount)
289 | {
290 | if (Application.isPlaying)
291 | GameObject.Destroy(item.image.gameObject);
292 | #if UNITY_EDITOR
293 | else
294 | GameObject.DestroyImmediate(item.image.gameObject);
295 | #endif
296 | item.image = null;
297 | }
298 | if (item.image == null)
299 | {
300 | inlineImages.RemoveAt(i);
301 | }
302 | }
303 | }
304 | SetVerticesDirty();
305 | m_FilterText = FilterRichText(m_Text);
306 | }
307 |
308 | private string m_OldNoFilterText;
309 | private string m_FilterText;
310 | private bool m_OldSupportRichText;
311 | public override void SetVerticesDirty()
312 | {
313 | base.SetVerticesDirty();
314 | if (m_OldNoFilterText != m_Text || m_OldSupportRichText != supportRichText)
315 | {
316 | m_OldNoFilterText = m_Text;
317 | m_OldSupportRichText = supportRichText;
318 | m_FilterText = FilterRichText(m_Text);
319 | }
320 | }
321 |
322 | [SerializeField] private List inlineImages = new List();
323 | private List inlineCharIndex = new List();
324 | private void SetInLineImageCull(int index, bool cull)
325 | {
326 | InLineImage item = inlineImages[index];
327 | if (item.image == null)
328 | return;
329 |
330 | item.cull = cull;
331 | if (cull != item.image.canvasRenderer.cull)
332 | {
333 | item.image.canvasRenderer.cull = cull;
334 | if (!cull)
335 | {
336 | item.image.Rebuild(CanvasUpdate.PreRender);//不加这个在隐藏状态时有变化不会更新
337 | }
338 | }
339 | }
340 |
341 | private string FilterRichText(string text)
342 | {
343 | inlineCharIndex.Clear();
344 | int i = 0;
345 | if (supportRichText)
346 | {
347 | Match match;
348 | do
349 | {
350 | match = s_Regex.Match(text);
351 | if (match.Success)
352 | {
353 | inlineCharIndex.Add(match.Index);
354 |
355 | string src = match.Groups[1].Value;
356 | float width = string.IsNullOrEmpty(match.Groups[2].Value) ? float.NaN : float.Parse(match.Groups[2].Value);
357 | float height = string.IsNullOrEmpty(match.Groups[3].Value) ? float.NaN : float.Parse(match.Groups[3].Value);
358 | string newText = "";
359 | Image img = null;
360 | if (i >= inlineImages.Count || inlineImages[i].image == null)
361 | {
362 | img = new GameObject("InlineImage" + (i + 1).ToString()).AddComponent();
363 | img.transform.SetParent(this.transform, false);
364 | img.raycastTarget = false;
365 | if (i < inlineImages.Count)
366 | {
367 | inlineImages[i].image = img;
368 | inlineImages[i].cull = false;
369 | }
370 | else
371 | inlineImages.Add(new InLineImage(img));
372 | }
373 | else
374 | {
375 | img = inlineImages[i].image;
376 | }
377 |
378 | LoadSprite(img, match.Groups[1].Value);
379 | Sprite spr = img.sprite;
380 | if (spr != null)
381 | {
382 | if (float.IsNaN(height) && float.IsNaN(width))
383 | {
384 | height = fontSize;
385 | width = height / spr.rect.height * spr.rect.width;
386 | }
387 | else if (float.IsNaN(width))
388 | {
389 | width = height / spr.rect.height * spr.rect.width;
390 | }
391 | else if (float.IsNaN(height))
392 | {
393 | height = width / spr.rect.width * spr.rect.height;
394 | }
395 | img.rectTransform.sizeDelta = new Vector2(width, height);
396 | newText = "";
399 | }
400 | text = text.Substring(0, match.Index) + newText + text.Substring(match.Index + match.Length);
401 | i++;
402 | }
403 | } while (match.Success);
404 | }
405 | int c = inlineImages.Count - 1;
406 | while (i <= c)
407 | {
408 | if (inlineImages[c].image != null)
409 | {
410 | inlineImages[c].image.sprite = null;
411 | SetInLineImageCull(c, true);
412 | }
413 | #if UNITY_EDITOR
414 | else
415 | {
416 | inlineImages.RemoveAt(c);
417 | }
418 | #endif
419 | c--;
420 | }
421 | return text;
422 | }
423 |
424 | readonly UIVertex[] m_TempVerts = new UIVertex[4];
425 | readonly UIVertex[] m_TempEffectVerts = new UIVertex[4];
426 | protected override void OnPopulateMesh(VertexHelper toFill)
427 | {
428 | if (font == null)
429 | return;
430 |
431 | // We don't care if we the font Texture changes while we are doing our Update.
432 | // The end result of cachedTextGenerator will be valid for this instance.
433 | // Otherwise we can get issues like Case 619238.
434 | m_DisableFontTextureRebuiltCallback = true;
435 |
436 | Vector2 extents = rectTransform.rect.size;
437 |
438 | var settings = GetGenerationSettings(extents);
439 | cachedTextGenerator.PopulateWithErrors(m_FilterText, settings, gameObject);//这里有缓存,不需要处理
440 | OnPopulateVertsPosition(toFill);
441 |
442 | m_DisableFontTextureRebuiltCallback = false;
443 | }
444 |
445 | protected virtual void OnPopulateVertsPosition(VertexHelper toFill)
446 | {
447 | // Apply the offset to the vertices
448 | IList verts = cachedTextGenerator.verts;
449 | float unitsPerPixel = 1 / pixelsPerUnit;
450 | //Last 4 verts are always a new line... (\n)
451 | int vertCount = verts.Count - 4;
452 |
453 | Vector2 roundingOffset = new Vector2(verts[0].position.x, verts[0].position.y) * unitsPerPixel;
454 | roundingOffset = PixelAdjustPoint(roundingOffset) - roundingOffset;
455 | toFill.Clear();
456 | bool needOffest = roundingOffset != Vector2.zero;
457 |
458 | //处理图文混排的图片
459 | int count = this.inlineCharIndex.Count;
460 | for (int i = 0; i < count; i++)
461 | {
462 | int index = inlineCharIndex[i];
463 | if (index * 4 + 3 < vertCount)
464 | {
465 | if (i < inlineImages.Count && inlineImages[i].image != null)
466 | {
467 | Vector2 topLeft = verts[index * 4 + 1].position;
468 | Vector2 bottomRight = verts[index * 4 + 3].position;
469 | Vector2 center = new Vector2((topLeft.x + bottomRight.x) * 0.5f, topLeft.y + (bottomRight.y - topLeft.y) * 0.6f);
470 | topLeft.y += (bottomRight.y - topLeft.y) * 0.5f;
471 | var image = inlineImages[i].image;
472 | image.transform.localPosition = center * unitsPerPixel;
473 | SetInLineImageCull(i, false);
474 | UIVertex newVertex = UIVertex.simpleVert;
475 | newVertex.position = center;
476 | verts[index * 4] = newVertex;
477 | verts[index * 4 + 1] = newVertex;
478 | verts[index * 4 + 2] = newVertex;
479 | verts[index * 4 + 3] = newVertex;
480 | }
481 | }
482 | else
483 | {
484 | if (i < inlineImages.Count)
485 | {
486 | SetInLineImageCull(i, true);
487 | }
488 | }
489 | }
490 |
491 | int charIndex = 0;
492 | bool hasCharOffests = charOffests != null && charOffests.Count > 0;
493 |
494 | float bottomY = float.MaxValue;
495 | float topY = float.MinValue;
496 | if (m_EnabledGradient)
497 | {
498 | for (int i = 0; i < vertCount; i += 2)
499 | {
500 | float y = verts[i].position.y;
501 | if (y > topY)
502 | {
503 | topY = y;
504 | }
505 | else if (y < bottomY)
506 | {
507 | bottomY = y;
508 | }
509 | }
510 | }
511 |
512 | for (int i = 0; i < vertCount; i += 4)
513 | {
514 | if (verts[i].position == verts[i + 1].position)
515 | continue;
516 |
517 | for (int j = 0; j < 4; ++j)
518 | {
519 | m_TempVerts[j] = verts[i + j];
520 | m_TempVerts[j].position *= unitsPerPixel;
521 | if (needOffest)
522 | {
523 | m_TempVerts[j].position.x += roundingOffset.x;
524 | m_TempVerts[j].position.y += roundingOffset.y;
525 | }
526 | }
527 |
528 | //文字位移
529 | float cosRotate = 0f;
530 | float sinRotate = 0f;
531 | if (hasCharOffests && charIndex < charOffests.Count)
532 | {
533 | CharOffest charOffest = charOffests[charIndex];
534 | bool needScale = charOffest.scale != Vector2.one;
535 | if (charOffest.rotation != 0f)
536 | {
537 | cosRotate = Mathf.Cos(charOffest.rotation);
538 | sinRotate = Mathf.Sin(charOffest.rotation);
539 | }
540 | if (charOffest != null)
541 | {
542 | Vector2 center = (m_TempVerts[0].position + m_TempVerts[2].position) / 2f;
543 | for (int j = 0; j < 4; ++j)
544 | {
545 | if (needScale)
546 | {
547 | m_TempVerts[j].position.x = center.x + (m_TempVerts[j].position.x - center.x) * charOffest.scale.x;
548 | m_TempVerts[j].position.y = center.y + (m_TempVerts[j].position.y - center.y) * charOffest.scale.y;
549 | }
550 | if (charOffest.rotation != 0f)
551 | {
552 | float dx = m_TempVerts[j].position.x - center.x;
553 | float dy = m_TempVerts[j].position.y - center.y;
554 | m_TempVerts[j].position.x = center.x + dx * cosRotate - dy * sinRotate;
555 | m_TempVerts[j].position.y = center.y + dx * sinRotate + dy * cosRotate;
556 | }
557 | m_TempVerts[j].position.x += charOffest.position.x;
558 | m_TempVerts[j].position.y += charOffest.position.y;
559 | }
560 | }
561 | }
562 |
563 | //渐变
564 | if (m_EnabledGradient)
565 | {
566 | ApplyGradientColor(m_TempVerts, color, m_GradientColor, topY, bottomY);
567 | }
568 |
569 | //阴影与描边
570 | if (m_EffectType != TextEffectType.NONE)
571 | {
572 | if (m_EffectType == TextEffectType.MATERIAL)
573 | {
574 | Vector2 bottomLeft = m_TempVerts[0].uv0;
575 | Vector2 topRight = m_TempVerts[2].uv0;
576 | if (bottomLeft.x > topRight.x)
577 | {
578 | bottomLeft = m_TempVerts[2].uv0;
579 | topRight = m_TempVerts[0].uv0;
580 | }
581 | Vector4 uvBounds = new Vector4(bottomLeft.x, bottomLeft.y, topRight.x, topRight.y);
582 | m_TempVerts[0].tangent = uvBounds;
583 | m_TempVerts[1].tangent = uvBounds;
584 | m_TempVerts[2].tangent = uvBounds;
585 | m_TempVerts[3].tangent = uvBounds;
586 | }
587 | else
588 | {
589 | m_TempVerts.CopyTo(m_TempEffectVerts, 0);
590 | ApplyColor(m_TempEffectVerts, m_EffectColor);
591 | ApplyOffestX(m_TempEffectVerts, m_EffectDistance.x);
592 | ApplyOffestY(m_TempEffectVerts, m_EffectDistance.y);
593 | toFill.AddUIVertexQuad(m_TempEffectVerts);
594 | if (m_EffectType != TextEffectType.SHADOW)
595 | {
596 | ApplyOffestY(m_TempEffectVerts, -m_EffectDistance.y - m_EffectDistance.y);
597 | toFill.AddUIVertexQuad(m_TempEffectVerts);
598 | ApplyOffestX(m_TempEffectVerts, -m_EffectDistance.x - m_EffectDistance.x);
599 | toFill.AddUIVertexQuad(m_TempEffectVerts);
600 | ApplyOffestY(m_TempEffectVerts, m_EffectDistance.y + m_EffectDistance.y);
601 | toFill.AddUIVertexQuad(m_TempEffectVerts);
602 | if (m_EffectType != TextEffectType.OUTLINE4)
603 | {
604 | const float sqrt2 = 1.414214f;
605 | ApplyOffestX(m_TempEffectVerts, m_EffectDistance.x);
606 | ApplyOffestY(m_TempEffectVerts, (sqrt2 - 1) * m_EffectDistance.y);
607 | toFill.AddUIVertexQuad(m_TempEffectVerts);
608 | ApplyOffestY(m_TempEffectVerts, -sqrt2 * 2 * m_EffectDistance.y);
609 | toFill.AddUIVertexQuad(m_TempEffectVerts);
610 | ApplyOffestY(m_TempEffectVerts, sqrt2 * m_EffectDistance.y);
611 | ApplyOffestX(m_TempEffectVerts, sqrt2 * m_EffectDistance.x);
612 | toFill.AddUIVertexQuad(m_TempEffectVerts);
613 | ApplyOffestX(m_TempEffectVerts, -sqrt2 * 2 * m_EffectDistance.x);
614 | toFill.AddUIVertexQuad(m_TempEffectVerts);
615 | }
616 | }
617 | }
618 | };
619 | toFill.AddUIVertexQuad(m_TempVerts);
620 | charIndex++;
621 | };
622 | }
623 |
624 | void ApplyColor(UIVertex[] vertexs, Color32 effectColor)
625 | {
626 | if (m_UseGraphicAlpha)
627 | effectColor.a = (byte)(effectColor.a * vertexs[0].color.a / 255);
628 | vertexs[0].color = effectColor;
629 | vertexs[1].color = effectColor;
630 | vertexs[2].color = effectColor;
631 | vertexs[3].color = effectColor;
632 | }
633 |
634 | void ApplyGradientColor(UIVertex[] vertexs, Color32 topColor, Color32 bottomColor, float topY, float bottomY)
635 | {
636 | if (m_UseGraphicAlpha)
637 | {
638 | topColor.a = (byte)(topColor.a * vertexs[0].color.a / 255);
639 | bottomColor.a = (byte)(bottomColor.a * vertexs[0].color.a / 255);
640 | }
641 | float uiElementHeight = topY - bottomY;
642 | vertexs[0].color = vertexs[1].color = Color32.Lerp(bottomColor, topColor, (vertexs[0].position.y - bottomY) / uiElementHeight);
643 | vertexs[2].color = vertexs[3].color = Color32.Lerp(bottomColor, topColor, (vertexs[2].position.y - bottomY) / uiElementHeight);
644 | }
645 |
646 | void ApplyOffestX(UIVertex[] vertexs, float v)
647 | {
648 | vertexs[0].position.x += v;
649 | vertexs[1].position.x += v;
650 | vertexs[2].position.x += v;
651 | vertexs[3].position.x += v;
652 | }
653 |
654 | void ApplyOffestY(UIVertex[] vertexs, float v)
655 | {
656 | vertexs[0].position.y += v;
657 | vertexs[1].position.y += v;
658 | vertexs[2].position.y += v;
659 | vertexs[3].position.y += v;
660 | }
661 |
662 |
663 | #if UNITY_EDITOR
664 | private readonly static Vector3[] fourCorners = new Vector3[4];
665 | private void OnDrawGizmosSelected()
666 | {
667 | if (this.raycastTarget)
668 | {
669 | Gizmos.color = Color.green;
670 | rectTransform.GetWorldCorners(fourCorners);
671 | for (int i = 0; i < 4; i++)
672 | {
673 | Gizmos.DrawLine(fourCorners[i], fourCorners[(i + 1) % 4]);
674 | }
675 | }
676 | }
677 |
678 | protected override void OnValidate()
679 | {
680 | base.OnValidate();
681 | UpdateVisible();
682 |
683 |
684 | }
685 | #endif
686 | }
687 | }
688 |
--------------------------------------------------------------------------------
/AdvancedComponent/AdvancedText.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 158dd5200e4d2634c99a208e0af5cad5
3 | timeCreated: 1509474729
4 | licenseType: Free
5 | MonoImporter:
6 | externalObjects: {}
7 | serializedVersion: 2
8 | defaultReferences: []
9 | executionOrder: 0
10 | icon: {instanceID: 0}
11 | userData:
12 | assetBundleName:
13 | assetBundleVariant:
14 |
--------------------------------------------------------------------------------
/AdvancedComponent/Editor.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 0e92a42c4b8ad0f4ea65c8bfa2bd86ea
3 | folderAsset: yes
4 | timeCreated: 1516558021
5 | licenseType: Pro
6 | DefaultImporter:
7 | externalObjects: {}
8 | userData:
9 | assetBundleName:
10 | assetBundleVariant:
11 |
--------------------------------------------------------------------------------
/AdvancedComponent/Editor/AdvancedImageEditor.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using UnityEngine.UI;
3 | using UnityEditor;
4 | using UnityEditor.AnimatedValues;
5 |
6 | namespace UGUIExtend
7 | {
8 | [CustomEditor(typeof(AdvancedImage), false)]
9 | [CanEditMultipleObjects]
10 |
11 | public class AdvancedImageEditor : UnityEditor.UI.ImageEditor
12 | {
13 | [MenuItem("GameObject/UI/Advanced Image", false, 3)]
14 | static void CreatePanel()
15 | {
16 | GameObject spriteObject = new GameObject("Sprite");
17 | if (Selection.activeGameObject != null)
18 | {
19 | spriteObject.transform.parent = Selection.activeGameObject.transform;
20 | spriteObject.layer = Selection.activeGameObject.layer;
21 | }
22 | else
23 | {
24 | Canvas mainCanvas = GameObject.FindObjectOfType