[UGUI]Image源码分析

unity版本5.3.5

一.属性

1.overrideSprite

脚本对精灵的访问均使用overrideSprite,如果m_OverrideSprite存在就使用m_OverrideSprite,否则使用m_Sprite,即优先级:m_OverrideSprite > m_Sprite

public Sprite overrideSprite { get { return m_OverrideSprite == null ? sprite : m_OverrideSprite; } set { if (SetPropertyUtility.SetClass(ref m_OverrideSprite, value)) SetAllDirty(); } }

2.preserveAspect

true表示保持原图的宽高比

二.方法

对于DataUtility类,可以看这个:https://www.cnblogs.com/lyh916/p/10611132.html

1.GenerateSimpleSprite

如果图片类型是Simple,那么就会进入这个方法。

GetDrawingDimensions:返回图片的绘制区域,例如下面的红框区域。值为(x,y,width,height),即起点和宽高

然后将4个顶点加入到VertexHelper中,顶点顺序如下:

2.xxx

三.位置和UV分布

参考UGUI的源码,可以写一个简单版本的Image,继承Image类,只保留Simple类型图片的绘制

Image2.cs

 1 using UnityEngine;
 2 using UnityEngine.UI;
 3 using UnityEngine.Sprites;
 4 
 5 public class Image2 : Image {
 6 
 7     protected override void OnPopulateMesh(VertexHelper toFill)
 8     {
 9         if (overrideSprite == null)
10         {
11             base.OnPopulateMesh(toFill);
12             return;
13         }
14 
15         switch (type)
16         {
17             case Type.Simple:
18                 GenerateSimpleSprite(toFill, preserveAspect);
19                 break;
20         }
21     }
22 
23     void GenerateSimpleSprite(VertexHelper vh, bool lPreserveAspect)
24     {
25         Vector4 v = GetDrawingDimensions(lPreserveAspect);
26         var uv = (overrideSprite != null) ? DataUtility.GetOuterUV(overrideSprite) : Vector4.zero;
27 
28         var color32 = color;
29         vh.Clear();
30         vh.AddVert(new Vector3(v.x, v.y), color32, new Vector2(uv.x, uv.y));
31         vh.AddVert(new Vector3(v.x, v.w), color32, new Vector2(uv.x, uv.w));
32         vh.AddVert(new Vector3(v.z, v.w), color32, new Vector2(uv.z, uv.w));
33         vh.AddVert(new Vector3(v.z, v.y), color32, new Vector2(uv.z, uv.y));
34 
35         vh.AddTriangle(0, 1, 2);
36         vh.AddTriangle(2, 3, 0);
37     }
38 
39     private Vector4 GetDrawingDimensions(bool shouldPreserveAspect)
40     {
41         var padding = overrideSprite == null ? Vector4.zero : DataUtility.GetPadding(overrideSprite);
42         var size = overrideSprite == null ? Vector2.zero : new Vector2(overrideSprite.rect.width, overrideSprite.rect.height);
43 
44         Rect r = GetPixelAdjustedRect();
45         // Debug.Log(string.Format("r:{2}, size:{0}, padding:{1}", size, padding, r));
46 
47         int spriteW = Mathf.RoundToInt(size.x);
48         int spriteH = Mathf.RoundToInt(size.y);
49 
50         var v = new Vector4(
51                 padding.x / spriteW,
52                 padding.y / spriteH,
53                 (spriteW - padding.z) / spriteW,
54                 (spriteH - padding.w) / spriteH);
55 
56         if (shouldPreserveAspect && size.sqrMagnitude > 0.0f)
57         {
58             var spriteRatio = size.x / size.y;
59             var rectRatio = r.width / r.height;
60 
61             if (spriteRatio > rectRatio)
62             {
63                 var oldHeight = r.height;
64                 r.height = r.width * (1.0f / spriteRatio);
65                 r.y += (oldHeight - r.height) * rectTransform.pivot.y;
66             }
67             else
68             {
69                 var oldWidth = r.width;
70                 r.width = r.height * spriteRatio;
71                 r.x += (oldWidth - r.width) * rectTransform.pivot.x;
72             }
73         }
74 
75         v = new Vector4(
76                 r.x + r.width * v.x,
77                 r.y + r.height * v.y,
78                 r.x + r.width * v.z,
79                 r.y + r.height * v.w
80                 );
81 
82         return v;
83     }
84 }

1.位置分布

当pivot为(0.5,0.5)时,位置分布如下。类推当pivot为(0,0)时,左下角为(0,0),右上角为(w,h)

2.UV分布

与pivot无关,uv的中心点对应图片的中心点,左下角为(uv.x, uv.y),右上角为(uv.z, uv.w)

原文地址:https://www.cnblogs.com/lyh916/p/10591044.html