粒子系统

实践内容

参考 http://i-remember.fr/en 这类网站,使用粒子流编程控制制作一些效果, 如“粒子光环”

参考博客

步骤

  1. 添加:粒子系统
    在 Hierarchy下,Effects →添加 Particle System,命名为ParticleHalo
    添加
    hallo

  2. 粒子系统脚本

    1) 新建ParticleHalo.cs 脚本
    2) 构建粒子结构体,记录粒子的半径、角度和时间

    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;       // 时间
            }
        }
    

    3) 设置需要用到的变量

    • 声明操作对象:包括粒子系统、粒子数组、粒子对应位置的数组CirclePosition
        private ParticleSystem particleSys;  // 粒子系统
        private ParticleSystem.Particle[] particleArr;  // 粒子数组
        private CirclePosition[] circle; // 极坐标数组
    
    • 声明粒子属性:数量、粒子大小、旋转的最大最小半径、旋转方向、旋转速度、粒子游离范围,从而可以控制光环的显示效果
        public int count = 10000;       // 粒子数量
        public float size = 0.10f;      // 粒子大小
        public float minRadius = 5.0f;  // 最小半径
        public float maxRadius = 12.0f; // 最大半径
        public bool clockwise = true;   // 顺时针|逆时针
        public float speed = 2f;        // 速度
        public float pingPong = 0.02f;  // 游离范围
    

    4)粒子系统初始化和启动

    • 根据设置的数量count来初始化粒子数组和粒子位置数组
    • 设置粒子大小和初速度,以及粒子最大数量
    • 发射粒子,并将粒子随机分布在圆环上
        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);
        }
    

    5)粒子系统旋转
    改变例子角度可以实现粒子的旋转,使旋转效果更加明显,可以给粒子的旋转添加灵活性

    • 为每个粒子设置不同的角速度:根据粒子索引分为不同的组,不同组的速度变化量不同
    • 允许粒子在一定半径范围内游离:利用数学库中的PingPong函数实现粒子运动的半径在一定范围内来回变动
    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));
                
                // 粒子在半径方向上游离
                circle[i].time += Time.deltaTime;
                circle[i].radius += Mathf.PingPong(circle[i].time / minRadius / maxRadius, pingPong) - pingPong / 2.0f;
    
                particleArr[i].color = colorGradient.Evaluate(circle[i].angle / 360.0f);
            }
    
            particleSys.SetParticles(particleArr, particleArr.Length);
        }
    

    6) 添加光效
    添加Gradient类,设置粒子颜色动态变化。在Update中让粒子颜色根据旋转角度产生一个变化

    public Gradient colorGradient;//添加Gradient变量
    
    particleArr[i].color = colorGradient.Evaluate(circle[i].angle / 360.0f);
    
  3. 显示设置
    在ParticleHalo的Inspector面板下,点击脚本ParticleHalo/Color Gradient,进行如下设置
    色彩
    设置相机Transform 和 Clear Flags(将背景设为黑色)
    相机
    运行
    结果

  4. 使粒子变亮
    这里的粒子亮度太暗,我们可以改变粒子大小或更换一个更亮的粒子材质,使显示效果更好

  • 设置粒子大小size 为0.1,运行
    设置size
    结果
    结果
  • 或者导入ParticleSystem资源包
    右键Assert → Import Package → ParticleSystems

导入资源包
选中Particlehalo物体,在Inspector下,展开Particle System → 展开Renderer → 点击Material选项按钮 → 更换为ParticleFirecloud的材质
选择材质
size设为0.05
运行结果
0.05
6. 再添加一个粒子系统作为内环
create Effect → 添加ParticleSystem,命名为Anticlochwise_inner,添加ParticleHalo.cs脚本
内环
调整参数
结果
结果
结果
视频

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值