UGUI进阶知识[二]自定义多边形image image精确点击以及 不继承monobehaviour的类如何在inspector显示自定义变量的编辑器知识

本文介绍了如何在Unity中自定义圆形Image组件,并实现精确点击功能,同时探讨了UGUI Mask组件的局限性和降低drawCall的方法。通过理解图像的顶点和像素颜色,使用等腰三角面片模拟圆形,以及掌握Unity的渲染原理,可以创建出高效且视觉效果良好的UI元素。此外,文章还讨论了非Monobehaviour类在Inspector中显示自定义变量的编辑器扩展技巧。
摘要由CSDN通过智能技术生成

网上关于自制UIMask的博客也不少了
丢掉Mask遮罩,更好的圆形Image组件[Unity]
这里在自学了一部分之后详细记录一下
圆形遮罩的原理 以及 在自制mask里面实现精确点击的原理 以及 部分的编辑器知识
目前的UGUI有mask组件,但是存在一些缺点:

  • drawCall高,在一些CPU与GPU交互速率比较低的机器上,drawcall高是造成卡顿的一个主要因素
  • 边界锯齿感强 明显粗糙不好看
  • 点击不准确

自制UIMask涉及到的知识属于稍微底层了
代码的看通需要读者对渲染知识了解
图像的成型需要顶点和像素颜色的辅助,顶点简单来说就是帮助形成一个形状的各个端点,像素颜色是顶点内部每个像素点需要表达的颜色
圆形可以由若干个相同的以圆心为顶点的等腰三角面片组成正多边形,近似模拟出来。三角面片分得多了,多边形的边越多,夹角越大,就越近似圆形。

在比较多的时候 要实现一些看似比较复杂比较难上手的UI任务的时候
可以查看unity的UGUI 源码 ,unity对UGUI开源

Image的主要原理
在这里插入图片描述
上图大约的描述了 圆形遮罩的 生成过程
图中的0代表了中心顶点
举例 顶点2 的横坐标与圆心的差距x1是通过半径乘以角a的余弦值得到
纵坐标与圆心的差距y1通过半径乘以角a的正弦值得到,其他的顶点是类似的
(x1 + 0的x坐标, y1 + 0的y坐标)描述了顶点的坐标
全部顶点的生成顺序是按图中的1 2 3 4 这样逆时针生成的
0 1 2 三个顶点 组成了一个三角面片
但是 组合三角面片的顺序是 1 0 2 这样的一个方向
在图中按照这个方向连线可以发现是顺时针方向
如果降低周围顶点数量 就可以从圆形降低到多边形
顶点生成的顺序是按照阿拉伯数字递增来生成的 即图中的逆时针
然后加入到顶点数组的顺序也是按照这个来放置的
后面生成三角面的时候 传入AddTriangle的顶点顺序在图中是按照顺时针的
即1 0 2 和 2 0 3 这样
这是根据了unity的成像原理,生成三角面传入的顶点顺序在屏幕上看需要是
顺时针才会进行渲染 否则 会被引擎认为是背面 (模型内部往外看就是背面)
一般来说 背面一般不会进行渲染

如果一个方形的image里面 放了个内切圆
则如果没有点到圆的部分的话 unity引擎里面是会依然识别到点击的
所以要自己去弄精确点击的部分
精确点击的原理
一个点向右发出射线 因为任何自定义形状都是闭合的
所以如果穿过自定义形状的边的次数是偶数(偶数包括0)
则这个点一定在外边,否则 就是在里面了

下面的脚本挂载在UI组件下 同时再挂载一个button组件即可

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Sprites;
using UnityEngine.UI;

public class CircleImage : Image
{
   
    
    //图片被分成的总片数
    [SerializeField]
    protected int totalSegments = 100;
    //显示部分占圆形的百分比.
    [SerializeField]
    private float cdOutPercent = 1;
    private readonly Color32 GRAY_COLOR = new Color32(60, 60, 60, 255);
    private List<Vector3> imgVertexPosList;

    /// <summary>
    /// 这个函数是image用于处理图像顶点的
    /// 重写这个方法可以定义顶点的处理过程
    /// 处理后的顶点要传回给VertexHelper
    /// 在c#里面 是不用加ref 和out 也能在被调用函数里面改变传进来的参数
    /// 使得调用函数的值不一样 具体百度
    /// </summary>
    /// <param name="vh"></param>
    protected override void OnPopulateMesh(VertexHelper vh)
    {
   
        //这里清除意义是不用unity内定的图片渲染顶点数据
        vh.Clear();

        imgVertexPosList = new List<Vector3>();

        GenVertex(vh, totalSegments);

        AddTriangle(vh, totalSegments);
    }

    private void GenVertex(VertexHelper vh, int segements)
    {
   
        float width = rectTransform.rect.width;
        float heigth = rectTransform.rect.height;
        int cdOutSegments = (int)(segements * cdOutPercent);

        //这里使用overrideSprite 因为使用Sprite的话 即使有赋值 有时会为空
        //DataUtility.GetOuterUV函数是获得图片的uv信息
        Vector4 uv = overrideSprite != null ? DataUtility.GetOuterUV(overrideSprite) : Vector4.zero;

        Debug.LogError("uv.x " + uv.x + " uv.y " + uv.y + " uv.z " + uv.z + " uv.w " + uv.w);


        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

染指流年丨

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

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

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

打赏作者

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

抵扣说明:

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

余额充值