unity之圆角头像实现

重写了一个image组件,将精灵拖进去可调整圆角的大小和平滑度,我写的这个只支持正方形图片,矩形会比较麻烦,暂时还没想到方法

实现思路:

1.如下图,image画图原理就是在一个方框中画三角形,然后形成图片,红线代表方框的坐标系,蓝色代表图片的坐标系,也就是你在这个方框的某个位置上画图片的哪个部位,例如蓝色的(0,0)点,假如image宽度,高度都为2,也就是在黑框的(-1,-1)画一个(0,0)点。

2.如果想要圆角就很简单了,就是在角上多画几个间距相等的点,点越多平滑度越高,例如我图中左上角多加了一个点,四边形也就成了五边形,得到5个点的集合,也就是图中的紫色数字。

3.画图是由很多个三角形构成,(注意添加三角形时,点的方向必须是顺时针的,例如(0,1,2),(2,3,4),(4,5,0)都可以),然后就可以用一个for循环,从0点开始添加三角形(i,i+1,i+2)。添加完成后图也就画好了~~~^_^~~~

4.点的位置,用sin和cos(90/(点的个数))*r(如果想画圆形r就是1/2)得到点在蓝色坐标的位置,红色坐标可以根据蓝色坐标得到,他两关系是固定的嘛。根据宽度得就行(ps:蓝色坐标中,图片的长宽都为1,而红色的是根据image实际的width和height)

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

时间: 2024-08-07 01:02:43

unity之圆角头像实现的相关文章

Unity用户自定义圆角头像

前天朋友遇到一个这样的需求,而且比较棘手让我帮忙解决.需求就是棋牌类的游戏,玩家的个人资料中包括自己的头像而且可以浏览相册中的图片或者使用相机拍照设置.关于这个问题我也查阅一些资料,由于涉及安卓部分知识,首先要了解Unity和安卓是如何通信的. 首先看到的是雨松老师的博客:http://www.xuanyusong.com/archives/1480咱们可以一起参考下这篇博客.好了,废话就不多说了,夜已深,开始撸代码吧! 1 新建空的工程 2,头像显示当然要用图片了,就用UGUI的RawImag

【android】 圆角头像

I:画圆角: 1 private void roundImg(ImageView iv){ 2 3 /**本地资源*/ 4 5 InputStream is = getResources().openRawResource(R.drawable.icon); 6 7 Bitmap bitmap = BitmapFactory.decodeStream(is); 8 9 /**网络资源*/ 10 11 //FileInputStream fis = new FileInputStream(url)

Android Demo---如何敲出圆角的Button+圆角头像

经常玩儿App的小伙伴都知道,APP上面有很多按钮都是圆角的,圆形给人感觉饱满,富有张力,不知道设计圆角按钮的小伙伴是不是和小编有着相同的想法`(*∩_∩*)′,听小编公司开发IOS的小伙伴说,他们里面直接有圆角的button,但是对于开发Android的小伙伴就不一样了,里面没有直接的圆角button可以供我们使用,在xml里面布局一个button,还不是圆角的,怎么办nie,方法总比困难多,我们成长的机会又来了,最近在小编的项目中,需要用到圆角的button,还需要用到圆角的头像,经过半天捣

圆角头像----CSS3特效

w3c:http://www.w3school.com.cn/cssref/pr_border-radius.asp 定义和用法 border-radius 属性是一个简写属性,用于设置四个 border-*-radius 属性. 提示:该属性允许您为元素添加圆角边框! 属性border-radius:50px; 这时候头像的外框就有圆角效果 div { border:2px solid; border-radius:50%; }

小程序圆角头像

<open-data type="userAvatarUrl" class="head-img"></open-data> .head-img {   width: 140rpx;   height: 140rpx;   border-radius: 50%;   margin-top: 40rpx;   display: block;   overflow: hidden; } 原文地址:https://www.cnblogs.com/xy

给头像设置圆角的卡顿解决

加入在tableView的每个cell里都有一个圆角头像,因为在layer.corner...开销过大,所以会造成卡顿,可以通过贝塞尔曲线进行绘制. // 如下所示 // Get your image somehow UIImage *image = [UIImage imageNamed:@"image.jpg"]; // Begin a new image that will be the new image with the rounded corners // (here wi

IOS 设置圆角用户头像

在App中有一个常见的功能,从系统相册或者打开照相机得到一张图片,然后作为用户的头像.从相册中选取的图片明明都是矩形的图片,但是展示到界面上却变成圆形图片,这个神奇的效果是如何实现的呢? 请大家跟着下面的步骤,去实现选取并展示圆角头像的功能吧! 一.设置显示头像的圆角图片 1. 显示用户头像用UIImageView实现,添加默认图片后效果如下图所示,头像显示为矩形图片. 代码实现: // ViewController.m // SetUserImage // // Created by jere

圆形头像CircleImageView和Cardview使用

效果: 圆形头像在我们的日常使用的app中很常见,因为圆形的头像比较美观. 使用圆形图片的方法可能有我们直接将图片裁剪成圆形再在app中使用, 还有就是使用自定义View对我们设置的任何图片自动裁剪成圆形. 这里使用github上CircleImageView github:https://github.com/hdodenhof/CircleImageView CardView顾名思义卡片式的View, CardView继承的是FrameLayout,所以摆放内部控件的时候需要注意一下 可以设

MonoTouch - iOS 使用 UIImagePickerController 打开图片库和相机选择图片修改头像

Application tried to present modally an active controller <UIImagePickerController: 0x7b6ff400> 1,AddGestureRecognizer为图片视图添加事件 //圆角头像 _avatarView = new UIImageView(new RectangleF(_blockSpace, _blockSpace, 2 * _avatarRadius, 2 * _avatarRadius)); UII