unity之圆角头像实现

Posted 糯米团子滚呀滚

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unity之圆角头像实现相关的知识,希望对你有一定的参考价值。

 这个是参考大神的修改了一下渲染方式实现的,可以去查看原帖的,原贴是圆形头像,原理讲的非常详细

点击这里

我写的这个只支持正方形图片,效果是酱紫的~

一共三个代码,还需要两个代码,原帖里都有的,我只是修改了其中一个。

 

  1 using System.Collections.Generic;
  2 using UnityEngine;
  3 using UnityEngine.UI;
  4 using UnityEngine.Sprites;
  5 
  6 [AddComponentMenu("UI/Circle Image")]
  7 public class CircleImage1 : BaseImage {
  8     // Use this for initialization
  9     void Awake () {
 10         innerVertices = new List<Vector3>();
 11         outterVertices = new List<Vector3>();
 12     }
 13 
 14     // Update is called once per frame
 15     void Update () {
 16 
 17     }
 18 
 19 
 20     [Range(0, 1)]
 21     public float scale = 1f;
 22 
 23     [Range(2, 30)]
 24     public int segements = 2;
 25 
 26     private List<Vector3> innerVertices;
 27     private List<Vector3> outterVertices;
 28 
 29     protected override void OnPopulateMesh(VertexHelper vh)
 30     {  vh.Clear();
 31         Rect pixelAdjustedRect = this.GetPixelAdjustedRect();
 32 
 33         Vector4 uv = overrideSprite != null ? DataUtility.GetOuterUV(overrideSprite) : Vector4.zero;
 34         //Debug.LogError("uv:" + uv+","+uv.w+","+uv.x+","+uv.y+","+uv.z);
 35 
 36          Vector2 u = new Vector2(0, 0);
 37         float w = pixelAdjustedRect.width;
 38       
 39         #region
 40         //1
 41         for (int i =0; i < segements+1; i++)
 42         {
 43             UIVertex uivertex = new UIVertex();
 44             uivertex.color = color;
 45             if (i ==0)
 46             {
 47                 //半径*
 48                 uivertex.uv0 = new Vector2(uv.x + (scale / 2) * (uv.z - uv.x) * (1 - Mathf.Sin(i * 90 / segements)), uv.y + (scale / 2) * (uv.w - uv.y) * (1 - Mathf.Cos(i * 90 / segements)));
 49                 u = new Vector2((scale / 2) * (1 - Mathf.Sin(i * 90 / segements)),(scale / 2) * (1 - Mathf.Cos(i * 90 / segements)));
 50             }
 51             else
 52             {
 53                 uivertex.uv0 = new Vector2(uv.x + (scale / 2) * (uv.z - uv.x) * (1 - Mathf.Sin(Mathf.PI / (180f / (i * 90 / segements)))), uv.y + (scale / 2) * (uv.w - uv.y) * (1 - Mathf.Cos(Mathf.PI / (180f / (i * 90 / segements)))));
 54                 u = new Vector2((scale / 2)  * (1 - Mathf.Sin(Mathf.PI / (180f / (i * 90 / segements)))),(scale / 2)  * (1 - Mathf.Cos(Mathf.PI / (180f / (i * 90 / segements)))));
 55             }
 56             uivertex.position = new Vector3(w * u.x - w / 2, w * u.y - w / 2);
 57             
 58             vh.AddVert(uivertex);
 59         }
 60         //2
 61         for (int i = 0; i < segements + 1; i++)
 62         {
 63             UIVertex uivertex = new UIVertex();
 64             uivertex.color = color;
 65             if (i == 0)
 66             {
 67                uivertex.uv0 = new Vector2(uv.x + (uv.z - uv.x) * (scale / 2) * (1 - Mathf.Cos(i * 90 / segements)), uv.y + (uv.w - uv.y) * ((1 - scale / 2) + (scale / 2) * Mathf.Sin(i * 90 / segements)));
 68                 u = new Vector2((scale / 2) - (scale / 2) * Mathf.Cos(i * 90 / segements), (1 - scale / 2) + (scale / 2) * Mathf.Sin(i * 90 / segements));
 69             }
 70             else
 71             {
 72                 uivertex.uv0 = new Vector2(uv.x + (uv.z - uv.x) * (scale / 2) * (1 - Mathf.Cos(Mathf.PI / (180f / (i * 90 / segements)))), uv.y + (uv.w - uv.y) * ((1 - scale / 2) + (scale / 2) * Mathf.Sin(Mathf.PI / (180f / (i * 90 / segements)))));
 73                 u = new Vector2( (scale / 2) * (1 - Mathf.Cos(Mathf.PI / (180f / (i * 90 / segements)))), (1 - scale / 2) + (scale / 2) * Mathf.Sin(Mathf.PI / (180f / (i * 90 / segements))));
 74             }
 75             uivertex.position = new Vector3(w * u.x - w / 2, w * u.y - w / 2);
 76             vh.AddVert(uivertex);
 77         }
 78         //3
 79         for (int i = 0; i < segements + 1; i++)
 80         {
 81             UIVertex uivertex = new UIVertex();
 82             uivertex.color = color;
 83             if (i == 0)
 84             {
 85                 uivertex.uv0 = new Vector2(uv.x + (uv.z - uv.x) * ((1 - scale / 2) + (scale / 2) * Mathf.Sin(i * 90 / segements)), uv.y + (uv.w - uv.y) * ((1 - scale / 2) + (scale / 2) * Mathf.Cos(i * 90 / segements)));
 86                u = new Vector2((1 - scale / 2) + (scale / 2) * Mathf.Sin(i * 90 / segements), (1 - scale / 2) + (scale / 2) * Mathf.Cos(i * 90 / segements));
 87             }
 88             else
 89             {
 90                 uivertex.uv0 = new Vector2(uv.x + (uv.z - uv.x) * ((1 - scale / 2) + (scale / 2) * Mathf.Sin(Mathf.PI / (180f / (i * 90 / segements)))), uv.y + (uv.w - uv.y) * ((1 - scale / 2) + (scale / 2) * Mathf.Cos(Mathf.PI / (180f / (i * 90 / segements)))));
 91                 u= new Vector2((1 - scale / 2) + (scale / 2) * Mathf.Sin(Mathf.PI / (180f / (i * 90 / segements))), (1 - scale / 2) + (scale / 2) * Mathf.Cos(Mathf.PI / (180f / (i * 90 / segements))));
 92             }
 93             uivertex.position = new Vector3(w * u.x - w / 2, w * u.y - w / 2);
 94             vh.AddVert(uivertex);
 95         }
 96         //4
 97         for (int i = 0; i < segements + 1; i++)
 98         {
 99             UIVertex uivertex = new UIVertex();
100             uivertex.color = color;
101             if (i == 0)
102             {
103                 uivertex.uv0 = new Vector2(uv.x + (uv.z - uv.x) * ((1 - scale / 2) + (scale / 2) * Mathf.Cos(i * 90 / segements)), uv.y + (uv.w - uv.y) * ((scale / 2) - (scale / 2) * Mathf.Sin(i * 90 / segements)));
104                 u  = new Vector2((1 - scale / 2) + (scale / 2) * Mathf.Cos(i * 90 / segements), (scale / 2) - (scale / 2) * Mathf.Sin(i * 90 / segements));
105             }
106             else
107             {
108                 uivertex.uv0 = new Vector2(uv.x + (uv.z - uv.x) * ((1 - scale / 2) + (scale / 2) * Mathf.Cos(Mathf.PI / (180f / (i * 90 / segements)))), uv.y + (uv.w - uv.y) * ((scale / 2) - (scale / 2) * Mathf.Sin(Mathf.PI / (180f / (i * 90 / segements)))));
109                 u = new Vector2((1 - scale / 2) + (scale / 2) * Mathf.Cos(Mathf.PI / (180f / (i * 90 / segements))), (scale / 2) - (scale / 2) * Mathf.Sin(Mathf.PI / (180f / (i * 90 / segements))));
110             }
111             uivertex.position = new Vector3(w * u.x - w / 2, w * u.y - w / 2);
112             vh.AddVert(uivertex);
113         }
114 
115         //((点*4+8个点-3)条弦+1)个三角形
116         for (int i = 0; i < ((segements - 1) * 4 + 8 - 3 + 1); i++)
117         {
118             vh.AddTriangle(0, i + 1, i + 2);
119         }
120         #endregion
121     }
122 
123     public override bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera)
124     {
125 //        Sprite sprite = overrideSprite;
126 //        if (sprite == null)
127 //            return true;
128 
129         
130     //    Debug.LogError("鼠标点击:" + screenPoint);
131         
132         
133 //        Vector2 local;
134 //        RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, screenPoint, eventCamera, out local);
135         return true;
136     }
137 
138     private bool Contains(Vector2 p, List<Vector3> outterVertices, List<Vector3> innerVertices)
139     {
140         var crossNumber = 0;
141         RayCrossing(p, innerVertices, ref crossNumber);//检测内环
142         RayCrossing(p, outterVertices, ref crossNumber);//检测外环
143         return (crossNumber & 1) == 1;
144     }
145 
146     /// <summary>
147     /// 使用RayCrossing算法判断点击点是否在封闭多边形里
148     /// </summary>
149     /// <param name="p"></param>
150     /// <param name="vertices"></param>
151     /// <param name="crossNumber"></param>
152     private void RayCrossing(Vector2 p, List<Vector3> vertices, ref int crossNumber)
153     {
154         for (int i = 0, count = vertices.Count; i < count; i++)
155         {
156             var v1 = vertices[i];
157             var v2 = vertices[(i + 1) % count];
158 
159             //点击点水平线必须与两顶点线段相交
160             if (((v1.y <= p.y) && (v2.y > p.y))
161                 || ((v1.y > p.y) && (v2.y <= p.y)))
162             {
163                 //只考虑点击点右侧方向,点击点水平线与线段相交,且交点x > 点击点x,则crossNumber+1
164                 if (p.x < v1.x + (p.y - v1.y) / (v2.y - v1.y) * (v2.x - v1.x))
165                 {
166                     crossNumber += 1;
167                 }
168             }
169         }
170     }
171 
172 }
View Code

 

以上是关于unity之圆角头像实现的主要内容,如果未能解决你的问题,请参考以下文章

登录圆形头像之网络加载与缓存到本地

Qt 圆角头像的实现

Android实现头像圆角

#yyds干货盘点#CSS实现随机不规则圆角头像

cocos2d-x JS 纯代码实现人物头像裁剪

SimpleRoundedImage-不使用mask实现圆角矩形图片