版权声明:本文为原创文章,转载请声明https://www.cnblogs.com/unityExplorer/p/13524824.html

使用UGUI进行游戏开发的过程中经常会遇到一个问题:玩家的头像在不同的界面或场景显示的形状可能不一样,有的地方需要显示成圆形,有些地方需要显示成方形

为了避免这种问题,我们选择殴打策划,恩。。。但是如果打策划打不过,美术小姐姐又不好意思打的话,怎么办?真出两套图,那不是一个精益求精的攻城狮乐意的看到的结果

有没有办法可以让同一张图可以显示成不同的形状呢?有的朋友说了,可以用UGUI的Mask来实现

这也是一种办法,但是这种办法有个弊端,就是遮罩图片尺寸很小的话,边缘锯齿会相当严重,这与UGUI中Mask的原理有关

所以有没有更好的办法呢?有的,我们先分析下UGUI图片的渲染原理

实际上,UGUI中的图片其实就是一个由两个三角面拼接成的平面模型

当场景中只有一张图片时,可以看到,Tris是2,Verts是4

基于此,将顶点围成的图形修改成圆形,那就实现了我们的目的

将n个三角形拼接到一起就是一个近似圆形的形状,比如:

实现代码如下:

    public class CircleImage : Image
{
public int segements = ;
public float fillPercent = ; protected override void OnPopulateMesh(VertexHelper vh)
{
vh.Clear(); float tw = rectTransform.rect.width;
float th = rectTransform.rect.height;
float outerRadius = 0.5f * Mathf.Min(tw, th);
float degreeDelta = * Mathf.PI / segements;
int curSegements = (int)(segements * fillPercent);
        
       //因UGUI的锚点系统,这里需要考虑pivot的差值,以避免因物体原点的改变导致图片歪了
Vector2 pivotVector = new Vector2(tw * (0.5f - rectTransform.pivot.x), th * (0.5f - rectTransform.pivot.y));
Vector4 uv = overrideSprite != null ? DataUtility.GetOuterUV(overrideSprite) : Vector4.zero;
Vector2 center = new Vector2(uv.x + uv.z, uv.y + uv.w) * 0.5f;
float uvScaleX = (uv.z - uv.x) / tw;
float uvScaleY = (uv.w - uv.y) / th; float curDegree = ;
UIVertex uiVertex;
int verticeCount;
int triangleCount;
Vector2 curVertice; curVertice = Vector2.zero;
verticeCount = curSegements + ;
uiVertex = new UIVertex
{
color = color,
position = curVertice + pivotVector,
uv0 = new Vector2(curVertice.x * uvScaleX, curVertice.y * uvScaleY) + center
};
vh.AddVert(uiVertex); for (int i = ; i < verticeCount; i++)
{
curVertice = new Vector2(Mathf.Cos(curDegree) * outerRadius, Mathf.Sin(curDegree) * outerRadius);
curDegree += degreeDelta; uiVertex = new UIVertex
{
color = color,
position = curVertice + pivotVector,
uv0 = new Vector2(curVertice.x * uvScaleX, curVertice.y * uvScaleY) + center
};
vh.AddVert(uiVertex);
} triangleCount = curSegements * ;
for (int i = , vIdx = ; i < triangleCount - ; i += , vIdx++)
{
vh.AddTriangle(vIdx, , vIdx + );
}
if (fillPercent == )
{
//首尾顶点相连
vh.AddTriangle(verticeCount - , , );
}
}
}

将正中心的点作为图形顶点的起始点,按照逆时针或顺时针方向画三角形,最终再回到中心点,就形成了一个封闭的圆形

三角面的数量决定了圆形的圆滑程度,作为组件,我们可以将三角面的数量作为参数对外暴露

这个组件继承自UGUI的Image,所以也拥有Image的部分属性,事实上出于性能开销考虑,继承RawImage性价比会更高

但是RawImage有个一个问题,就是不兼容图集系统,也就是说,即使是打在图集中的图片,如果使用RawImage,内存会额外计算,综合考虑下,也只能这样了

unity探索者之UGUI圆形图片组件的更多相关文章

  1. unity探索者之UGUI图片描边

    版权声明:本文为原创文章,转载请声明https://www.cnblogs.com/unityExplorer/p/13524270.html 自从UGUI出现之后,我就已经放弃使用NGUI了,原因不 ...

  2. 丢掉Mask遮罩,更好的圆形Image组件[Unity]

    写在前面 全文解析圆形Image组件的实现原理,取关键代码介绍算法细节,源码已经上传Github下载地址,欢迎下载试用. 一.Unity原生Image组件实现圆形图片的缺陷 Mask渲染消耗 许多游戏 ...

  3. 在Unity中使用UGUI修改Mesh绘制几何图形

    在商店看到这样一个例子,表示很有兴趣,他们说是用UGUI做的.我想,像这种可以随便变形的图形,我第一个就想到了网格变形. 做法1: 细心的朋友应该会发现,每个UGUI可见元素,都有一个‘Canvas ...

  4. Unity关于一个UGUI优化效率的方法

    无意间发现了一个小技巧.如下图所示,可以发现UGUI的Image组件的RaycastTarget勾选以后会消耗一些效率,为了节省效率就不要勾选它了,不仅Image组件Text组件也有这样的问题. 一般 ...

  5. [UGUI]圆形Image

    参考链接: http://www.cnblogs.com/leoin2012/p/6425089.html 前面说过Mask组件会影响性能:https://www.cnblogs.com/lyh916 ...

  6. Unity教程之-UGUI一个优化效率小技巧

    无意间发现了一个小技巧.如下图所示,可以发现UGUI的Image组件的RaycastTarget勾选以后会消耗一些效率,为了节省效率就不要勾选它了,不仅Image组件Text组件也有这样的问题. 一般 ...

  7. 关于Unity中的UGUI优化,你可能遇到这些问题

    https://blog.uwa4d.com/archives/QA_UGUI-1.html 关于Unity中的UGUI优化,你可能遇到这些问题 作者:admin / 时间:2016年11月08日 / ...

  8. Android 自定义圆形图片 CircleImageView

    1.效果预览 1.1.布局中写自定义圆形图片的路径即可 1.2.然后看一看图片效果 1.3.原图是这样的 @mipmap/ic_launcher 2.使用过程 2.1.CircleImageView源 ...

  9. flutter 图片组件

    加入图片的几种方式 Image.asset:加载资源图片,就是加载项目资源目录中的图片,加入图片后会增大打包的包体体积,用的是相对路径. Image.network:网络资源图片,意思就是你需要加入一 ...

随机推荐

  1. Linux 终端最全推荐(建议收藏)

    本文来自网络整理,如有侵权,则可删除. 如果你跟我一样,整天要花大量的时间使用Linux命令行,而且正在寻找一些可替代系统自带的老旧且乏味的终端软件,那你真是找对了文章.我这里搜集了一些非常有趣的终端 ...

  2. 理解Spring(二):AOP 的概念与实现原理

    目录 什么是 AOP AOP 的基本术语 Spring AOP 的简单应用 Spring AOP 与动态代理 Spring AOP 的实现原理(源码分析) 扩展:为什么 JDK 动态代理要求目标类必须 ...

  3. linux日志朔源分析记录

    lastlog 记录用户最后一次登录情况 只有root最近登录过 lastlog -u 用户名或者uid uid 直接在passwd文件中的低三位可以看到 lastb 记录用户用户登录失败的用户记录, ...

  4. Flask前后端分离项目案例

    简介 学习慕课课程,Flask前后端分离API后台接口的实现demo,前端可以接入小程序,暂时已经完成后台API基础架构,使用postman调试. git 重构部分: token校验模块 auths认 ...

  5. lua 表

    最近在尝试配置 awesome WM,因此粗略地学习了一下 lua . 在学习过程中,我完全被表表在 lua 中的应用所镇住了. 表在 lua 中真的是无处不在:首先,它可以作为字典和数组来用:此外, ...

  6. 干货 | 这可能全网最好的BatchNorm详解

    文章来自:公众号[机器学习炼丹术].求关注~ 其实关于BN层,我在之前的文章"梯度爆炸"那一篇中已经涉及到了,但是鉴于面试经历中多次问道这个,这里再做一个更加全面的讲解. Inte ...

  7. 【工具】 - BeanUtils增强篇

    public class BeanPlusUtils extends BeanUtils { public static <S, T> List<T> copyListProp ...

  8. PHP str_rot13() 函数

    实例 编码并解码字符串: <?php高佣联盟 www.cgewang.comecho str_rot13("Hello World");echo "<br&g ...

  9. P4221 [WC2018]州区划分 无向图欧拉回路 FST FWT

    LINK:州区划分 把题目中四个条件进行规约 容易想到不合法当前仅当当前状态是一个无向图欧拉回路. 充要条件有两个 联通 每个点度数为偶数. 预处理出所有状态. 然后设\(f_i\)表示组成情况为i的 ...

  10. luogu P4632 [APIO2018] New Home 新家 线段树 set 二分

    写了一种比较容易理解 但是常数很大的sol. 容易发现可以扫描线. 维护好序列之后发现很难查距离 考虑二分. 这里二分可以在线段树上进行 当然可能存在一些问题 如果离散化的话需要处理一些比较麻烦的细节 ...