unity中Image组件的uv形状为矩形,要显示圆形的图片可以使用遮罩、使用形状为矩形但是实际所有像素点的形状为圆形的图片等方法,这些方法各有优劣,这里使用脚本继承Image组件并重写其中的OnPopulateMesh方法将uv改为圆形
public class CircleImage : Image { //圆形由多少扇形(实际上是近似扇形的三角形)拼成 private int segements = 100; protected override void OnPopulateMesh(VertexHelper vertexHelper) { //清除继承的image的原有的图片绘制信息 vertexHelper.Clear(); //获取uv信息,四维向量uv的四个坐标分别代表图片矩形框左下角和右上角顶点的横纵坐标 Vector4 uv = overrideSprite == null ? Vector4.zero : DataUtility.GetOuterUV(overrideSprite); //获取图片宽高和uv的宽高 float imageWidth = rectTransform.rect.width; float imageHeigh = rectTransform.rect.height; float uvWidth = uv.z - uv.x; float uvHeigh = uv.w - uv.y; //获取uv的中心点位置 Vector2 uvCenter = new Vector2(uvWidth * 0.5f, uvHeigh * 0.5f); //求得图片像素和uv方框的换算比例 Vector2 converRatio = new Vector2(uvWidth / imageWidth, uvHeigh / imageHeigh); //求得每个扇形弧度 float radian = (2 * Mathf.PI) / segements; //规定半径 float radius = imageWidth * 0.5f; //生成初始顶点(原点),并给初始顶点赋值 UIVertex origin = new UIVertex(); origin.color = color; origin.position = Vector2.zero; //使用前面计算的图片像素和uv方框的换算比例计算顶点uv对应的图片点位置 origin.uv0 = new Vector2(origin.position.x * converRatio.x + uvCenter.x, origin.position.y * converRatio.y + uvCenter.y); //添加顶点 vertexHelper.AddVert(origin); //循环遍历生成并添加其他顶点信息 float curRadian = 0; for(int i = 0;i <= segements; i++) { //计算顶点坐标 float x = Mathf.Cos(curRadian) * radius; float y = Mathf.Sin(curRadian) * radius; curRadian += radian; //生成并添加顶点信息 UIVertex vertexTemp = new UIVertex(); vertexTemp.color = color; vertexTemp.position = new Vector2(x,y); vertexTemp.uv0 = new Vector2(vertexTemp.position.x * converRatio.x + uvCenter.x, vertexTemp.position.y * converRatio.y + uvCenter.y); vertexHelper.AddVert(vertexTemp); } //遍历生成所有的三角形面片 int id = 1; for (int i = 0; i < segements; i++) { //三个参数代表三角形的三个顶点,注意顶点顺序,面片的前后遵循左手定则(即叉乘结果的方向为前方) vertexHelper.AddTriangle(id, 0, id + 1); id++; } } }