UGUI源码解析——Image

一:前言

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


二:源码解析—属性

——overrideSprite、sprite和activeSprite

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


——mainTexture

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


——preferredWidth和preferredHeight

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


三:源码解析—方法

——OnEnable和OnDisable

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


——TrackSprite、TrackImage、UnTrackImage、RebuildImage

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


——OnPopulateMesh

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

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


——UpdateMaterial

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


——SetNativeSize

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


——PreserveSpriteAspectRatio

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


——IsRaycastLocationValid

判断是否可以通过射线
——判断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);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hello Bug.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值