您的位置:首页 > 产品设计 > UI/UE

使用UGUI自定义五边形

2016-01-12 11:29 746 查看
using UnityEngine;
using System.Collections.Generic;
using UnityEngine.UI;

/*
*
*           5
*
*
*   6       0       4
*
*
*      1    2    3
*
*
*
*/

public class UIPropWidget : Graphic
{
private const int VERTEX_SIZE = 8;                  // 必须为4的倍数  通过绘制两个四边形组成一个五边形

private List<Vector2> _currentList = new List<Vector2>();

private Vector2 vec0 = new Vector2(0, 0);
private Vector2 vec1;
private Vector2 vec2;
private Vector2 vec3;
private Vector2 vec4;
private Vector2 vec5;
private Vector2 vec6;

private float cos18;
private float sin18;

private float cos36;
private float sin36;

private float rate = 1f;
private float radius = 100f;

void Awake(){
Init();
}

void Update()
{
SetVerticesDirty();
}

public void Init(){

float angle36 = 36*Mathf.PI/180;
float angle18 = 18*Mathf.PI/180;

cos18 = Mathf.Cos(angle18);
sin18 = Mathf.Sin(angle18);

cos36 = Mathf.Cos(angle36);
sin36 = Mathf.Sin(angle36);

vec1 =  new Vector2(-radius*sin36*rate, -radius*cos36*rate);
vec3 =  new Vector2(radius*sin36*rate, -radius*cos36*rate);
vec4 =  new Vector3(radius*cos18*rate, radius*sin18*rate);
vec5 =  new Vector3(0, radius*rate);
vec6 =  new Vector3(-radius*cos18*rate, radius*sin18*rate);

//通过两点式算出1,3直线与y轴的交点
vec2 =  new Vector2(0, (0 - vec1.x)/(vec3.x - vec1.x)*(vec3.y - vec1.y) + vec1.y);

_currentList.Add(vec1);
_currentList.Add(vec2);
_currentList.Add(vec5);
_currentList.Add(vec6);
_currentList.Add(vec2);
_currentList.Add(vec3);
_currentList.Add(vec4);
_currentList.Add(vec5);

SetVerticesDirty();
}

private void UpdateVertex(List<UIVertex> vbo, List<Vector2> list)
{
// 必须要保证填充的是4的倍数
for (int i = 0; i < VERTEX_SIZE; ++i) {
var vert = UIVertex.simpleVert;
vert.color = color;
vert.position = list[i];
vbo.Add(vert);
}
}

protected override void OnFillVBO(List<UIVertex> vbo)
{
UpdateVertex(vbo, _currentList);
}
}


一个CanvasRenderer进行绘制,所有的控件和可显示的元素都是Graphic。Graphic持有一个canvasRenderer,通过SetVertices设置顶点,最终完成绘制。 举例来说,Image控件就是一个Graphic,这个GameObject上面同时还有一个CanvasRenderer,两者结合起来最终把图片绘制完成。

以五边形中心点为原点,求出五个顶点1, 4, 3, 6, 7以及底边中心点2的位置

因为uGUI的绘制元素是Quad而不是三角形,SetVertices中设置的顶点数目必须是4的倍数,所以用他们组成两个四边形 1,2,3,4和5,6,7,8用这两个四边形组成一个五边形

给的坐标是相对于自己的坐标系的像素坐标(相对于自已的privot)假设我要绘制一个100*100的矩形,privot是(0.5,0.5),四个顶点的坐标则分别为(-50,-50),(50, -50),(50, 50),(-50, 50)

最后补充一些关于vertex设置的知识点。

一个控件的GameObject上面只允许有一个Graphic,所以不可能同时存在Image和Text。 我们自定义形状的控件可以通过两种方式来实现,一种是重载Graphic,这样这个控件就与Image等价,这里有两个比较重要的可以重载的函数 UpdateGeometry和OnFillVBO。如果看下uGUI的源代码可以发现,UpdateGeometry其实就是获取一个List,调用OnFillVBO设置顶点数据,再调用所有的BaseVertexEffect组件进行顶点修改,最后传递给canvasRenderer。 OnFillVBO就是我们常用的设置顶点的地方,只要在里面给vbo的参数Add数据就可以了,重复一下上文说过的,Add的数目必须是4的倍数。 Image和Text都是通过这里设置顶点数据的。

上面有提到BaseVertexEffect,这个就是另外一个可以修改顶点信息的地方,它是一个修饰的组件,以Text和Outline为例,Text是一个Graphic,在控件上面添加的Outline就是一个BaseVertexEffect,Graphic在运行的时候会获取控件上面所有的BaseVertexEffect,然后设置顶点的时候依次调用。 我们可以实现一个自定义效果,继承自BaseVertexEffect,然后重载ModifyVertex函数进行顶点设置。

原文链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: