0
点赞
收藏
分享

微信扫一扫

UGUI源码解析——Image


一:前言

Image是显示图像的组件,继承自MaskableGraphic,只能显示Sprite类型的贴图
大多应用于某个UI图标或者一些小图,还有一些需要九宫拉伸的图

二:源码解析—属性

——overrideSprite、sprite和activeSprite

UGUI源码解析——Image_ide


Image最终使用的是activeSprite,如果overrideSprite不为空则使用overrideSprite,否则使用sprite ——mainTexture

UGUI源码解析——Image_ide_02


如果activeSprite不为空则使用activeSprite的贴图,如果activeSprite为空则使用材质材质上的贴图,如果材质上的贴图为空则使用Texture2D.whiteTexture,最终会将mainTexture交给Canvas进行绘制 ——preferredWidth和preferredHeight

UGUI源码解析——Image_ide_03


实现ILayoutElement接口,计算最佳宽度和高度,只有在Image Type是Simple或Filled下才能使用

三:源码解析—方法

——OnEnable和OnDisable

UGUI源码解析——Image_java_04


调用TrackSprite和UnTrackImage处理Sprite上的贴图为空的情况 ——TrackSprite、TrackImage、UnTrackImage、RebuildImage

UGUI源码解析——Image_贴图_05


如果Sprite不为空但是Sprite上的Texture为空则视为此Image为追踪对象,OnEnable时将此对象添加到m_TrackedTexturelessImages列表中,重建图集和图像 ——OnPopulateMesh

UGUI源码解析——Image_java_06


重写了OnPopulateMesh方法修改元素的顶点、颜色、UV等信息存到m_VertexHelper中,最终会将m_VertexHelper传入Mesh并交给Canvas进行绘制

​​UGUI源码解析——Graphic​​

我们知道Image绘制图片时会使用简单的四边形(四个顶点两个三角形)进行绘制,如果勾选上useSpriteMesh则会使用TextureImporter生成的Sprite网格,这会增加顶点数和三角形数,没有特殊情况下不要勾选

——UpdateMaterial

UGUI源码解析——Image_贴图_07


对带有Alpha通道的图片进行渲染操作,如果原图片采取含有透明通道的压缩方式则调用SetAlphaTexture设置透明贴图,若不含有透明通道,则设置为null

​​UGUI源码解析——Graphic​​ ——SetNativeSize

UGUI源码解析——Image_ide_08


设置rectTransform为图片的原尺寸,需要与pixelsPerUnit一起计算,pixelsPerUnit默认为1 ——PreserveSpriteAspectRatio

UGUI源码解析——Image_java_09


保持原图片的宽高比,仅用于ImageType为Simple和Filled ——IsRaycastLocationValid

UGUI源码解析——Image_贴图_10


判断是否可以通过射线

——判断alphaHitTestMinimumThreshold的值,如果小于等于0则肯定能通过射线,如果大于1则永远不会通过射线检测

——调用RectTransformUtility.ScreenPointToLocalPointInRectangle判断鼠标位置是否在RectTransform内

——将屏幕位置转换为以左下角为起始点的坐标系MapCoordinate,然后转换为纹理空间坐标,最后通过调用Texture2D.GetPixelBilinear取得以标准化坐标的像素颜色的alpha值与alphaHitTestMinimumThreshold作比较(注意如果使用alphaHitTestMinimumThreshold需要开启图片的可读写访问)

四:自己编写简单Image

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Sprites;

public class SimpleImage: Graphic
{
public Sprite sprite;

public override Texture mainTexture
{
get
{
if (sprite == null)
{
if (material != null && material.mainTexture != null)
{
return material.mainTexture;
}
return s_WhiteTexture;
}
return sprite.texture;
}
}

protected override void Start()
{
}

protected override void OnPopulateMesh(VertexHelper vh)
{
vh.Clear();

//图片uv
Vector4 uv = sprite == null ? Vector4.zero : DataUtility.GetOuterUV(sprite);

//绘制位置
Rect rect = GetPixelAdjustedRect();
Vector4 v = new Vector4(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height);

Color32 c = color;
vh.AddVert(new Vector2(v.x, v.y), c, new Vector2(uv.x, uv.y));
vh.AddVert(new Vector2(v.x, v.w), c, new Vector2(uv.x, uv.w));
vh.AddVert(new Vector2(v.z, v.w), c, new Vector2(uv.z, uv.w));
vh.AddVert(new Vector2(v.z, v.y), c, new Vector2(uv.z, uv.y));
vh.AddTriangle(0, 1, 2);
vh.AddTriangle(2, 3, 0);
}
}

举报

相关推荐

0 条评论