技能冷却图标实现

转载说明:http://www.unitymanual.com/home.php?mod=space&uid=2265&do=blog&view=me&from=space&page=1

一、

一般3d游戏中技能冷却都会有个旋转遮罩,很多人都是使用NGUI、DFGUI等插件中的相关功能去实现,并不知道自己该如何去制作,今天我们就来讲述下自己制作一个这样的效果的流程

技能icon一般是一个矩形 遮罩从矩形的中心进行旋转

分析一下,我们可以将这个矩形分为8个三角

技能冷却图标实现_第1张图片

这样看是不是有所启发呢,没错,我们所要使用的方法就是操作这些三角形来实现一个圆周的旋转

技能冷却图标实现_第2张图片如图,我们将三角形0 1 2的1点 进行x轴位移至11,12,13点 这个旋转的雏形是不是就出来了呢

,然后看图分析 将三角形 0 2 3的2点进行y轴位移  依次类推整个圆周的旋转就大功告成了,原理篇就到这里,实现篇敬请期待。



二、


在开始实现冷却效果之前,我们得先了解 Mesh即网格对象以及我们所要用到的3个变量

Mesh.vertices    网格顶点
Mesh.triangles   三角形
Mesh.colors      顶点颜色


在使用Mesh之前 我们需要先获得Mesh的实例才能对其进行操作,
所以这里我们需要用到MeshFilter,
因为需要在旋转时对Mesh对象进行操作,所以我们采用的必须为MeshFilter.sharedMesh即共享网格
给Icon对象添加MeshFilter组件,在Start方法里创建共享网格meshFilter.sharedMesh = new Mesh();

注:下文所操作的Mesh皆为meshFilter.sharedMesh


根据第一章我们的分析得出 我们需要8个三角形及10个顶点
所以这里我们需要申明10个网格顶点
Mesh.vertices=new Vector3[10];

技能冷却图标实现_第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即宽高的一半,通过这两个值可以获得我们所需要的几个顶点位置,不理解的朋友可以位置和图片对比下进行理解。


顶点创建完毕,依旧看上面的图片进行分析,得出各个三角形,对Mesh.triangles进行赋值
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
        };
    }
对照图片可以清晰的理解这个数据声明原理,这里不再赘述。

顶点和三角形赋值完毕后 对各个顶点颜色进行赋值,因颜色可能各个icon的需求不同 所以这里给脚本定义一个外部传入参数 public Color color;

将传入颜色赋值给Mesh的各个顶点
Color[] colors = new Color[mesh.vertices.Length];
        for (int i = 0; i < colors.Length; ++i)
        {
            colors[i] = color;
        }

        mesh.colors = colors;
  
至此,实现效果的Mesh对象初始化数据就完成了,后续的实现,敬请期待。

三、

本章进行技能冷却的实现


基本思路 根据技能冷却的时间 求出每个三角形所需要的时间

根据流逝时间 获取当前操作的三角形索引
最终根据三角形索引进行 三角形顶点位移

代码如下,请根据注释来进行每一步的理解

[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;
    }
}


你可能感兴趣的:(技能冷却图标实现)