粒子系统

本文详细介绍如何使用粒子流编程控制在Unity中实现粒子光环效果。通过定义粒子结构体、控制粒子系统参数,以及在Start()和Update()方法中初始化和更新粒子位置,实现了动态光环效果。文章还介绍了如何通过调整参数使光环效果更加多样化。
作业要求

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

参考资料

https://blog.youkuaiyun.com/simba_scorpio/article/details/51251126

实验过程
1. 添加粒子系统

创建空对象ParticleHalo,再它下面建立新的空子对象Clockwise_outer。

ParticleHalo下面可以有很多不同的粒子系统,这些粒子系统有不同的参数,之后再设定。

在这里插入图片描述
在这里插入图片描述

2. 粒子系统脚本

需要定义每个粒子不同的位置、运动角度、运动速度等参数,并通过调整这些参数来模拟每个粒子的运动,从而获得“粒子光环”的效果。

2.1 粒子结构体

表示每个粒子的半径、角度和时间。


public class CirclePosition
{
    public float radius = 0f, angle = 0f, time = 0f;
    public CirclePosition(float radius, float angle, float time)
    {
        this.radius = radius;   // 半径
        this.angle = angle;     // 角度
        this.time = time;       // 时间
    }
}
2.2 私有变量

需要控制的粒子系统和粒子数组,以及每个粒子的CirclePosition。

	private ParticleSystem particleSys;  // 粒子系统
    private ParticleSystem.Particle[] particleArr;  // 粒子数组
    private CirclePosition[] circle; // 极坐标数组

为了达到光环的效果,还需要控制所有粒子的整体效果,包括数量、最大半径、最小半径、旋转方向、速度、游离范围:

    public int count = 10000;       // 粒子数量
    public float size = 0.03f;      // 粒子大小
    public float minRadius = 5.0f;  // 最小半径
    public float maxRadius = 12.0f; // 最大半径
    public bool clockwise = true;   // 顺时针|逆时针
    public float speed = 2f;        // 速度
    public float pingPong = 0.02f;  // 游离范围
2.3 Start()

初始化粒子数组,并将所有的粒子随机分布在圆圈轨道上


    void Start ()
    {   // 初始化粒子数组
        particleArr = new ParticleSystem.Particle[count];
        circle = new CirclePosition[count];
 
        // 初始化粒子系统
        particleSys = this.GetComponent<ParticleSystem>();
        particleSys.startSpeed = 0;            // 粒子位置由程序控制
        particleSys.startSize = size;          // 设置粒子大小
        particleSys.loop = false;
        particleSys.maxParticles = count;      // 设置最大粒子量
        particleSys.Emit(count);               // 发射粒子
        particleSys.GetParticles(particleArr);
 
        RandomlySpread();   // 初始化各粒子位置
    }


   void RandomlySpread()
    {
        for (int i = 0; i < count; ++i)
        {   // 随机每个粒子距离中心的半径,同时希望粒子集中在平均半径附近
            float midRadius = (maxRadius + minRadius) / 2;
            float minRate = Random.Range(1.0f, midRadius / minRadius);
            float maxRate = Random.Range(midRadius / maxRadius, 1.0f);
            float radius = Random.Range(minRadius * minRate, maxRadius * maxRate);
 
            // 随机每个粒子的角度
            float angle = Random.Range(0.0f, 360.0f);
            float theta = angle / 180 * Mathf.PI;
 
            // 随机每个粒子的游离起始时间
            float time = Random.Range(0.0f, 360.0f);
 
            circle[i] = new CirclePosition(radius, angle, time);
 
            particleArr[i].position = new Vector3(circle[i].radius * Mathf.Cos(theta), 0f, circle[i].radius * Mathf.Sin(theta));
        }
 
        particleSys.SetParticles(particleArr, particleArr.Length);
    }
2.4 Update()

逐渐改变粒子的角度以让粒子旋转起来,同时为了有粒子闪动的效果:

  • 让粒子运动角度的变化量不一样。
  • 让粒子的运动半径不固定,使其能在半径方向上游离,此时用到time来随机。
	void Update () {
        for (int i = 0; i < count; i++) {
            if (clockwise)  // 顺时针旋转
                circle[i].angle -= (i % tier + 1) * (speed / circle[i].radius / tier);
            else            // 逆时针旋转
                circle[i].angle += (i % tier + 1) * (speed / circle[i].radius / tier);

            // 保证angle在0~360度
            circle[i].angle = (360.0f + circle[i].angle) % 360.0f;
            float theta = circle[i].angle / 180 * Mathf.PI;

            particleArr[i].position = new Vector3(circle[i].radius * Mathf.Cos(theta), 0f, circle[i].radius * Mathf.Sin(theta));

            particleArr[i].color = colorGradient.Evaluate(circle[i].angle / 360.0f);

            circle[i].time += Time.deltaTime;
            circle[i].radius += Mathf.PingPong(circle[i].time / minRadius / maxRadius, pingPong) - pingPong / 2.0f;
        }

        particleSys.SetParticles(particleArr, particleArr.Length);

    }
3. 增加旋转不同的粒子系统

在这里插入图片描述
给不同的粒子系统设置不同的参数,使粒子的变化更随机一点

在这里插入图片描述

游戏效果
github传送门

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值