UGUI能量图

UGUI能量图

游戏中为了展现角色属性,突出职业特点,经常用到“六芒星”,玩家可以根据六芒星的形状,更好的分析当前角色的属性和特点,如图:

fe08a713495409231e16ab5d9158d109b2de49d4

最近正在研究UGUI,为了理解UGUI组织顶点渲染的机制,就用UGUI实现了一套“六芒星”。

在Canvas节点下,所有显示的UI控件都有一个CanvasRenderer组件,这个组件就是用来组织UI控件顶点的。CanvasRenderer有设置Mesh的接口,通过角色的属性,构建出六芒星mesh,并传递给CanvasRenderer,使其符合UGUI渲染机制(深度,Order等)统一渲染。

Unity提供渲染网格接口类就是Mesh,通过Mesh我们可以设置顶点属性(位置,uv,颜色等),以及Mesh的顶点索引数组,就可以构建一个完整的Mesh对象了。为了使其在Canvas中正常显示,我们实例化一个Shader作为Material对象,赋值到CanvasRenderer组件对象中,即可完成渲染。

我们以六芒星为例,六芒星将平面360度平均划分为6份,每份60度,即可确定每个属性的方向,再根据属性的值(相当于向量的模),就可以得到对应的“属性向量”,将6个属性向量的终点连在一起,就可以渲染出整体的六芒星。

为了便于扩展六芒星为“五芒星”,“七芒星”等,我们允许设置以下几个属性:

startDirection:第一个属性的方向,通过这个方向值以及每个属性之间的角度,可以得到其他属性的方向。

attributes:属性数组,数组的长度表示了“N芒星”。

fullStrength:满属性值,通过属性值/满属性值,可以得到这个属性的比例,用于构建六芒星UI控件。

1
2
3
4
5
6
// 起始方向
public Vector3 startDirection = new Vector3(0, 1, 0);
// 星属性
public int [] attributes = null ;
// 最大值
public float fullStrength = 100f;

通过将360度平均划分为N份,以及向量旋转公式,可以得到每个属性的方向向量,算法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 获取每个属性点的方向向量
  int starsCount = this .attributes.Length;
  List<Vector3> directionList = new List<Vector3>(starsCount);
  float deltaAngle = this .circle / starsCount;
  for ( int i = 0; i < attributes.Length; ++i)
  {
      float angle = i * deltaAngle;
      float rad = Mathf.Deg2Rad * angle;
      float sinA = Mathf.Sin(rad);
      float cosA = Mathf.Cos(rad);
      directionList.Add( new Vector3(startDirection.x * cosA + startDirection.y * sinA,
  -startDirection.x * sinA + startDirection.y * cosA, 0));
  }

接下来计算六芒星中各顶点的位置,要构建六芒星,除了每个属性的顶点外,还需要一个中心点。属性点根据每个属性的方向(单位向量)*属性值可得,算法如下:

1
2
3
4
5
6
7
8
9
10
11
Mesh mesh = new Mesh();
// 设置顶点位置属性
int verticesCount = starsCount + 1;
List<Vector3> vertices = new List<Vector3>(verticesCount);
vertices.Add(Vector3.zero);
for ( int i = 1; i < verticesCount; ++i)
{
     int index = i - 1;
     vertices.Add(directionList[index] * this .attributes[index] / this .fullStrength * rectTransform.sizeDelta.x);
}
mesh.SetVertices(vertices);

为了表现更丰富一点,我们为每个属性设置一个颜色,属性的颜色值根据属性强度变深,算法如下:

1
2
3
4
5
6
7
8
9
10
11
// 设置颜色属性
List<Color32> colors = new List<Color32>();
colors.Add( new Color32(255, 255, 255, 255));
for ( int i = 0; i < starsCount; ++i)
{
     float strength = attributes[i] / rectTransform.sizeDelta.x;
     byte r = ( byte )(strength * 200);
     Color32 c = new Color32(r, 0, 0, 255);
     colors.Add(c);
}
mesh.SetColors(colors);

Mesh对象的顶点属性设置完成后,还要为顶点设置索引数组,六芒星网格是由6个三角形构建而成,这6个三角形有一个共点(中心点),通过中心点及任意两个相邻的属性顶点组成6个三角形,算法如下:

1
2
3
4
5
6
7
8
9
10
11
// 设置索引属性
int [] indices = new int [3 * starsCount];
for ( int i = 0; i < starsCount; ++i)
{
     int index = 3 * i;
     indices[index] = 0;
     indices[index + 1] = i + 1;
     indices[index + 2] = (i + 2) > starsCount ? (i + 2 - starsCount) : (i + 2);
}
mesh.SetIndices(indices, MeshTopology.Triangles, 0);
canvasRenderer.SetMesh(mesh);

最后设置材质

1
2
Material material = new Material(Shader.Find( "UI/Default" ));
canvasRenderer.SetMaterial(material, null );

效果如下图

QQ截图20160628175841

源码地址

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值