【Unity 3D游戏开发学习笔记】粒子光环

实现如下图的粒子光环:
参考网站:http://i-remember.fr/en
思路:
首先声明定义一个类用于存储每个粒子的半径和角度

public class particleClass {
    public float radius = 0.0f; // initialize
    public float angle = 0.0f; // initialize
    public particleClass(float radius_, float angle_)
    {
        radius = radius_;
        angle = angle_;
    }
}

定义声明一些需要用到的变量,如最大粒子数目,粒子的数组和存储粒子半径和角度类的数组,内环和外环的半径,粒子旋转的速度和分组,分组用于确定粒子顺时针或逆时针旋转。

public int maxParticlesNum = 6000; // the max number of particles
public ParticleSystem particleSystem;
private ParticleSystem.Particle[] particlesArray;
private particleClass[] paticleObject;
public float minRadius = 3.5f; // inner race radius
public float maxRadius = 10.0f; // outer race radius
public float speed = 0.23f; // the speed of particles
public int group = 2; // group 1 rotates clockwise and group 2
                      // rotates anticlockwise

Start函数内初始化两个数组的大小,并且获得粒子对象,然后进行遍历,对每个粒子的位置进行随机设置,但这里实际上需要使得粒子尽可能位于环的中心,也就是(maxRaidus+minRadius)/2的位置,下面是直接采用了1个算法。随后就存储每个粒子的位置信息和设置他的位置。

void Start() {
        particlesArray = new ParticleSystem.Particle[maxParticlesNum];
        paticleObject = new particleClass[maxParticlesNum];
        particleSystem.maxParticles = maxParticlesNum;
        particleSystem.Emit(maxParticlesNum);
        particleSystem.GetParticles(particlesArray);

        for (int i = 0; i < maxParticlesNum; i++) { 
            //random angle produced
            float randomAngle = Random.Range(0.0f, 360.0f);

            // random radius which is closed to the midRadius in a large probility produced
            float midRadius = (maxRadius + minRadius) / 2;
            // quote someone else's algorithm
            float minRate = Random.Range(1.0f, midRadius / minRadius);
            float maxRate = Random.Range(midRadius / maxRadius, 1.0f);
            float randomRadius = Random.Range(minRadius * minRate, maxRadius * maxRate);

            //set two arrays
            // save a new particle's radius & angle
            paticleObject[i] = new particleClass(randomRadius, randomAngle);
            // confirm its position
            particlesArray[i].position = new Vector3(randomRadius * Mathf.Cos(randomAngle), randomRadius * Mathf.Sin(randomAngle), 0.0f);
        }
        //set particle
        particleSystem.SetParticles(particlesArray, maxParticlesNum);
    }

Update函数中,采用奇数和偶数ID来分成两个组,并且按照i和group来更新他的速度(可以改其他表达式,做到每个粒子速度不会全部相同即可),然后要更新他的角度,因为角度有周期,可能超过360度,采用取余即可避免这个问题,再次更新粒子位置。

void Update() {
        // run setting, devided in 2 group
        for (int i = 0; i < maxParticlesNum; i++) {
            if (i % 2 == 0) { // judge if this particle should be group 1
                paticleObject[i].angle += (i % group + 1) * speed;
            } else { // or  group 2
                paticleObject[i].angle -= (i % group + 1) * speed;
            }
            //set new position according to the new angle
            paticleObject[i].angle = paticleObject[i].angle % 360;

            float new_angle = paticleObject[i].angle / 180 * Mathf.PI;
            particlesArray[i].position = new Vector3(paticleObject[i].radius * Mathf.Cos(new_angle), paticleObject[i].radius * Mathf.Sin(new_angle), 0f);
        }
        particleSystem.SetParticles(particlesArray, maxParticlesNum);
    }

Inspector设置:
这里写图片描述
运行结果:
这里写图片描述

完整代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ParRotation : MonoBehaviour {
    public class particleClass {
        public float radius = 0.0f; // initialize
        public float angle = 0.0f; // initialize
        public particleClass(float radius_, float angle_)
        {
            radius = radius_;
            angle = angle_;
        }
    }
    public int maxParticlesNum = 6000; // the max number of particles
    public ParticleSystem particleSystem;
    private ParticleSystem.Particle[] particlesArray;
    private particleClass[] paticleObject;
    public float minRadius = 3.5f; // inner race radius
    public float maxRadius = 10.0f; // outer race radius
    public float speed = 0.23f; // the speed of particles
    public int group = 2; // group 1 rotates clockwise and group 2 rotates anticlockwise

    void Start() {
        particlesArray = new ParticleSystem.Particle[maxParticlesNum];
        paticleObject = new particleClass[maxParticlesNum];
        particleSystem.maxParticles = maxParticlesNum;
        particleSystem.Emit(maxParticlesNum);
        particleSystem.GetParticles(particlesArray);

        for (int i = 0; i < maxParticlesNum; i++) { 
            //random angle produced
            float randomAngle = Random.Range(0.0f, 360.0f);

            // random radius which is closed to the midRadius in a large probility produced
            float midRadius = (maxRadius + minRadius) / 2;
            // quote someone else's algorithm
            float minRate = Random.Range(1.0f, midRadius / minRadius);
            float maxRate = Random.Range(midRadius / maxRadius, 1.0f);
            float randomRadius = Random.Range(minRadius * minRate, maxRadius * maxRate);

            //set two arrays
            // save a new particle's radius & angle
            paticleObject[i] = new particleClass(randomRadius, randomAngle);
            // confirm its position
            particlesArray[i].position = new Vector3(randomRadius * Mathf.Cos(randomAngle), randomRadius * Mathf.Sin(randomAngle), 0.0f);
        }
        //set particle
        particleSystem.SetParticles(particlesArray, maxParticlesNum);
    }

    void Update() {
        // run setting, devided in 2 group
        for (int i = 0; i < maxParticlesNum; i++) {
            if (i % 2 == 0) { // judge if this particle should be group 1
                paticleObject[i].angle += (i % group + 1) * speed;
            } else { // or  group 2
                paticleObject[i].angle -= (i % group + 1) * speed;
            }
            //set new position according to the new angle
            paticleObject[i].angle = paticleObject[i].angle % 360;

            float new_angle = paticleObject[i].angle / 180 * Mathf.PI;
            particlesArray[i].position = new Vector3(paticleObject[i].radius * Mathf.Cos(new_angle), paticleObject[i].radius * Mathf.Sin(new_angle), 0f);
        }
        particleSystem.SetParticles(particlesArray, maxParticlesNum);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值