转载说明:http://www.unitymanual.com/home.php?mod=space&uid=2265&do=blog&view=me&from=space&page=1
一、
一般3d游戏中技能冷却都会有个旋转遮罩,很多人都是使用NGUI、DFGUI等插件中的相关功能去实现,并不知道自己该如何去制作,今天我们就来讲述下自己制作一个这样的效果的流程
分析一下,我们可以将这个矩形分为8个三角形
这样看是不是有所启发呢,没错,我们所要使用的方法就是操作这些三角形来实现一个圆周的旋转
如图,我们将三角形0 1 2的1点 进行x轴位移至11,12,13点 这个旋转的雏形是不是就出来了呢
,然后看图分析 将三角形 0 2 3的2点进行y轴位移 依次类推整个圆周的旋转就大功告成了,原理篇就到这里,实现篇敬请期待。
二、
在开始实现冷却效果之前,我们得先了解 Mesh即网格对象以及我们所要用到的3个变量
根据图分析 各个点之间是有一定规则排列的 0点为中心 其他点则围绕0点绕一圈,我们这里假设Icon的高度和宽度为1 ,则顶点坐标数据声明如下
Mesh.vertices[0] = new Vector3(0.0f, 0.0f, 0.0f);
Mesh.vertices[1] = new Vector3(0.0f, halfHeight, 0.0f);
Mesh.vertices[2] = new Vector3(halfWidth, halfHeight, 0.0f);
Mesh.vertices[3] = new Vector3(halfWidth, 0.0f, 0.0f);
Mesh.vertices[4] = new Vector3(halfWidth, -halfHeight, 0.0f);
Mesh.vertices[5] = new Vector3(0.0f, -halfHeight, 0.0f);
Mesh.vertices[6] = new Vector3(-halfWidth, -halfHeight, 0.0f);
Mesh.vertices[7] = new Vector3(-halfWidth, 0.0f, 0.0f);
Mesh.vertices[8] = new Vector3(-halfWidth, halfHeight, 0.0f);
Mesh.vertices[9] = new Vector3(0.0f, halfHeight, 0.0f);
这里的halfWidth和halfHeight即宽高的一半,通过这两个值可以获得我们所需要的几个顶点位置,不理解的朋友可以位置和图片对比下进行理解。
三、
本章进行技能冷却的实现
[code]
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
[AddComponentMenu("Ace/Skill/Mask")]
public class MyMask : MonoBehaviour {
private MeshFilter meshFilter;
private Vector3[] verts = new Vector3[10];
private float halfWidth = 0.5f;
private float halfHeight = 0.5f;
private float start;//开始时间
private float total;//技能冷却时间
private float once;
public Color color;
private bool play = false;
void Start () {
meshFilter=GetComponent<MeshFilter>();
meshFilter.sharedMesh = new Mesh();
ResetVertices();
SetMeshVertices(meshFilter.sharedMesh);
setTriangles(meshFilter.sharedMesh);
setColor(meshFilter.sharedMesh);
startMovice(30);
}
void OnMouseUp() {
startMovice(60);
}
public void startMovice(float time) {
if (play) return;
total = time;
once = total / 8;//这里用8个三角形 总时间算出每个三角形需要耗时
renderer.enabled = true;//每次开始让描绘对象可见
ResetVertices();//每次开始重置顶点数据
play = true;
}
private void ResetVertices()
{
verts[0] = new Vector3(0.0f, 0.0f, 0.0f);
verts[1] = new Vector3(0.0f, halfHeight, 0.0f);
verts[2] = new Vector3(halfWidth, halfHeight, 0.0f);
verts[3] = new Vector3(halfWidth, 0.0f, 0.0f);
verts[4] = new Vector3(halfWidth, -halfHeight, 0.0f);
verts[5] = new Vector3(0.0f, -halfHeight, 0.0f);
verts[6] = new Vector3(-halfWidth, -halfHeight, 0.0f);
verts[7] = new Vector3(-halfWidth, 0.0f, 0.0f);
verts[8] = new Vector3(-halfWidth, halfHeight, 0.0f);
verts[9] = new Vector3(0.0f, halfHeight, 0.0f);
}
// 设置Mesh顶点数据
private void SetMeshVertices(Mesh mesh)
{
Vector3[] vertices = new Vector3[verts.Length];
for (int i = 0; i < verts.Length; ++i)
{
vertices[i] = verts[i];
}
mesh.vertices = vertices;
}
private void setColor(Mesh mesh)
{
Color[] colors = new Color[mesh.vertices.Length];
for (int i = 0; i < colors.Length; ++i)
{
colors[i] = color;
}
mesh.colors = colors;
}
private void setTriangles(Mesh mesh)
{
mesh.triangles = new int[]{
0,1,2,
0,2,3,
0,3,4,
0,4,5,
0,5,6,
0,6,7,
0,7,8,
0,8,9
};
}
// Update is called once per frame
void FixedUpdate()
{
if (!play) return;
UpdateEffect(meshFilter.sharedMesh);
}
public void UpdateEffect(Mesh mesh)
{
float now = Time.time - start;
if (now >=total) { renderer.enabled = false; return; }
// 更新顶点数据
Vector3[] vertices = mesh.vertices;
float percent = (now % once) / once; // 每个三角面遮罩的百分比
int index = (int)(now / once) + 1; // 当前修改的顶点索引
for (int i = index; i >0; --i)
{
switch (index)
{
case 1:
vertices[i].x = halfWidth * percent;
break;
case 2:
vertices[i].y = halfHeight - halfHeight * percent;
break;
case 3:
vertices[i].y = -halfHeight * percent;
break;
case 4:
vertices[i].x = halfWidth * (1 - percent);
break;
case 5:
vertices[i].x = -halfWidth * percent;
break;
case 6:
vertices[i].y = -halfHeight * (1 - percent);
break;
case 7:
vertices[i].y = halfHeight * percent;
break;
case 8:
vertices[i].x = -halfWidth + halfWidth * percent;
break;
}
}
mesh.vertices = vertices;
}
}