转载说明: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即宽高的一半,通过这两个值可以获得我们所需要的几个顶点位置,不理解的朋友可以位置和图片对比下进行理解。
三、
本章进行技能冷却的实现
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; } }