unity3D学习7 粒子系统

粒子系统


设计要求

使用粒子流编程控制制作一些效果,如“粒子光环”

制作过程

首先我来构思一下要做出什么效果。我预期效果是能够出现旋转的圆环,然后在圆环中绘制出一个魔法阵,然后魔法阵收缩最后爆炸。整个过程都可以使用粒子系统来完成,其中爆炸效果我们在课上已经完成了,所以这里就直接使用。

粒子系统属性设置

我觉得粒子系统最麻烦的就是调参数。粒子系统的参数实在是太多了,我使用的参数如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这套参数做出来的效果大致就是一些细小的红色闪光点,我就用这个来绘制我的图案。

实现代码

在实现代码中,我是对每一个粒子进行控制从而做出我需要的效果。动画播放的不同阶段我就使用计时的方法,到达一个时间点就切换到另一个动画,这种方法可能不太好,但是实现起来比较方便。

public class Main : MonoBehaviour
{
    public ParticleSystem particleSystem;
    public ParticleSystem boomSystem;
    private ParticleSystem.Particle[] particlesArray;
    float r;
    int merge_count;
    Vector3[] targets;
    Vector3[] target_centers;
    float[] angles;
    float spendTime;
    // Start is called before the first frame update
    void Start()
    {
        var Explotion = GameObject.Find("MyExposion");
        boomSystem = Explotion.GetComponent<ParticleSystem>();
        boomSystem.maxParticles = 0;
        spendTime = 0f;
        r = 0f;
        merge_count = 0;
        int particleNum = 9000;
        particleSystem.maxParticles = particleNum;
        targets = new Vector3[particleNum];
        target_centers = new Vector3[6];
        particlesArray = new ParticleSystem.Particle[particleNum];
        angles = new float[particleNum];
        for (int i = 0; i < particleNum; i++)
        {
            targets[i] = new Vector3(0f, 0f, 0f);
            float ranx = Random.Range(0f, 5f);
            float rany = Random.Range(0f, 5f);
            angles[i] = Random.Range(0, 2 * Mathf.PI);
        }
    }
    

    void Update() //动画播放顺序
    {
        spendTime += Time.deltaTime;
        if (spendTime <= 2) CircleExpand();
        else if (spendTime <= 11) CircleRotate();
        else if (spendTime <= 20) Merge();
        else if (spendTime <= 30) DrawMode();
        else if (spendTime <= 34) CircleClose();
        else if (spendTime <= 35.5) boom();
        else boomSystem.maxParticles = 0;
    }

    void CircleExpand() //圆环扩张
    {
        particleSystem.GetParticles(particlesArray);
        for (int i = 0; i < particlesArray.Length; i++)
        {
            float v_x = Mathf.Cos(angles[i]);
            float v_y = Mathf.Sin(angles[i]);
            particlesArray[i].position += new Vector3(v_x, v_y, 0f) * 0.1f;
        }
        r += 0.1f;
        Debug.Log(r);
        particleSystem.SetParticles(particlesArray, particlesArray.Length);
    }

    void CircleRotate() //圆环旋转
    {
        Vector3 axis = new Vector3(0, 0, 1f);
        this.transform.RotateAround(this.transform.position, axis, 10 * Time.deltaTime);
    }

    void Merge() //圆环凝聚成六个点
    {
        for(int i = 0; i < 6; i++)
        {
            float angle = Mathf.PI / 3 * (float)i + Mathf.PI / 6;
            target_centers[i] = new Vector3(r * Mathf.Cos(angle), r * Mathf.Sin(angle), 0);
        }
        particleSystem.GetParticles(particlesArray);
        for (int i = merge_count; i < particlesArray.Length && i < merge_count+50; i++)
        {
            int pos = Random.Range(0, 6);
            float ran_x = Random.Range(-0.1f, 0.1f);
            float ran_y = Random.Range(-0.1f, 0.1f);
            particlesArray[i].position = target_centers[pos] + new Vector3(ran_x,ran_y, 0);
            targets[i] = particlesArray[i].position;
        }
        merge_count += 50;
        particleSystem.SetParticles(particlesArray, particlesArray.Length);
    }

    void DrawMode() //粒子绘制阵型
    {
        particleSystem.GetParticles(particlesArray);
        for (int i = 0; i < particlesArray.Length; i++)
        {
            if(targets[i] == particlesArray[i].position)
            {
                int pos = Random.Range(0, 6);
                float ran_x = Random.Range(-0.1f, 0.1f);
                float ran_y = Random.Range(-0.1f, 0.1f);
                targets[i] = target_centers[pos] + new Vector3(ran_x, ran_y, 0);
            }
            else
            {
                float MoveSpeed = Random.Range(0f, 20f);
                particlesArray[i].position = Vector3.MoveTowards(particlesArray[i].position, targets[i], MoveSpeed * Time.deltaTime);
            }
        }
        particleSystem.SetParticles(particlesArray, particlesArray.Length);
    }

    void CircleClose() //粒子收缩回圆心
    {
        particleSystem.GetParticles(particlesArray);
        for (int i = 0; i < particlesArray.Length; i++)
        {
            float v_x = Mathf.Cos(angles[i]);
            float v_y = Mathf.Sin(angles[i]);
            particlesArray[i].position *= 0.97f;
        }
        particleSystem.SetParticles(particlesArray, particlesArray.Length);
    }

    void boom() //播放爆炸动画
    {
        boomSystem.maxParticles = 4;
    }
}

运行效果

在这里插入图片描述
可以看到,确实做出来了我预期的效果(魔法阵收缩然后爆炸的时候把我看笑了^ - ^,画风突变)。完整工程可以查看我的github, 如果有什么问题的话请大家及时指出,谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值