粒子系統——作業與練習

粒子光環製作

參考 http://i-remember.fr/en 這類網站,使用粒子流編程控制製作一些效果, 如“粒子光環”

在本次作業中,我使用粒子系統製作了一個彩虹效果的煙花。

基本步驟

首先,新建一個空對象Halo,並添加子對象,然後加入粒子系統:

然後新建腳本Halo,在腳本中完成具體粒子效果的實現。


    private ParticleSystem particleSys;  // 粒子系統
    private ParticleSystem.Particle[] particleArr;  // 粒子數組  
    private ParticleInfo[] particles; // 粒子位置數組
    public Gradient colorGradient; // 粒子顏色改變器
    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;  // 遊離範圍

首先在Halo中聲明需要用到的相關變量,包括了粒子系統、數組、位置數組以及粒子的數量、大小和半徑範圍等參數。

    public class ParticleInfo
    {
        public float radius = 0f, angle = 0f, time = 0f;
        public ParticleInfo(float x, float y, float z)
        {
            radius = x;
            angle = y;
            time = z;
        }
    }

ParticleInfo類定義了每個粒子的半徑、角度和時間,方便之後的處理。

    void RandomlySpread()
    {
        for (int i = 0; i < count; i ++)
        {
            // 隨機粒子距離中心的半徑
            float midR = (maxRadius + minRadius) / 2;
            float minRate = Random.Range(1, midR / minRadius);
            float maxRate = Random.Range(midR / maxRadius, 1);
            float R = Random.Range(minRadius * minRate, maxRadius * maxRate);

            // 隨機每個粒子的角度  
            float angle = Random.Range(0, 360);
            float theta = angle / 180 * Mathf.PI;

            // 隨機每個粒子的遊離起始時間  
            float time = Random.Range(0.0f, 360.0f);
            particles[i] = new ParticleInfo(R, angle, time);
            particleArr[i].position = new Vector3(particles[i].radius * Mathf.Cos(theta), 0f, particles[i].radius * Mathf.Sin(theta));
        }
        particleSys.SetParticles(particleArr, particleArr.Length);
    }

RandomlySpread函數用來賦予每個粒子一個初始的位置,在一定範圍內隨機生成每個粒子的位置、角度遊離時間。我們希望粒子總體集中在平均半徑附近,這樣看起來比較美觀。

    // Start is called before the first frame update
    void Start()
    {
        //initialize
        particleArr = new ParticleSystem.Particle[count];
        particles = new ParticleInfo[count];

        // 初始化粒子系統
        particleSys = this.GetComponent<ParticleSystem>();
        particleSys.startSpeed = 0;            // 粒子位置由程序控制
        particleSys.startSize = size;          // 設置粒子大小
        particleSys.loop = false;
        particleSys.maxParticles = count;      // 設置最大粒子量
        particleSys.Emit(count);               // 發射粒子
        particleSys.GetParticles(particleArr);

        RandomlySpread();   // 初始化各粒子位置

    }

Start中初始化粒子數組和粒子系統,並初始化粒子的位置(調用RandomlySpread函數)。

    void Update()
    {
        for (int i = 0; i < count; i++)
        {
            if (clockwise) 
                particles[i].angle -= (i % tier + 1) * (speed / particles[i].radius / tier);
            else          
                particles[i].angle += (i % tier + 1) * (speed / particles[i].radius / tier);

            particles[i].angle = (360.0f + particles[i].angle) % 360.0f;
            float theta = particles[i].angle / 180 * Mathf.PI;
            float x = 10 * Mathf.Sin(8 * theta) * Mathf.Cos(theta);
            float y = 10 * Mathf.Sin(8 * theta) * Mathf.Sin(theta);
            particleArr[i].position = new Vector3(x, 0f, y + Random.Range(-1f, 1f));

            // 粒子在半徑方向上游離  
            particles[i].time += Time.deltaTime;
            particles[i].radius += Mathf.PingPong(particles[i].time / minRadius / maxRadius, pingPong) - pingPong / 2.0f;

            //改變粒子透明度
            particleArr[i].color = colorGradient.Evaluate(Random.value);

        }

        particleSys.SetParticles(particleArr, particleArr.Length);
    }

Update函數用來更新粒子的位置,首先通過設置一個差分層變量tier將粒子系統分爲十層,每一層角度的增量都不相同,這就使得粒子系統的運動更加美觀。clockwise決定旋轉的方向。由於總體是圓形,所以要保證粒子的角度在0-360度之間。此外,還有一個PingPong函數,使得粒子在一個半徑範圍內來回地波動。
爲了使粒子系統呈現煙花的形狀。我在這裏使用了玫瑰線函數,該函數圖像及參數方程如下:
r = 10
x = rsin(10t)cos(t)
y = r
sin(10*t)*sin(t)

可以通過調整數值來改變葉片的數量。

通過將粒子數組的position設置爲該函數來使得粒子系統呈現煙花狀:

            float theta = particles[i].angle / 180 * Mathf.PI;
            float x = 10 * Mathf.Sin(8 * theta) * Mathf.Cos(theta);
            float y = 10 * Mathf.Sin(8 * theta) * Mathf.Sin(theta);
            particleArr[i].position = new Vector3(x, 0f, y + Random.Range(-1f, 1f));

最後,創建三個粒子系統,並分別加上紅黃藍三種顏色,將它們疊加在一起,最後就可以看到一個彩虹色的煙花了:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章