本次作業基本要求是三選一
1、簡單粒子制作
- 按參考資源要求,制作一個粒子系統,參考資源
- 使用 3.3 節介紹,用代碼控制使之在不同場景下效果不一樣
2、完善官方的“汽車尾氣”模拟
- 使用官方資源資源 Vehicle 的 car, 使用 Smoke 粒子系統模拟啟動發動、運作、故障等場景效果
3、參考 http://i-remember.fr/en 這類網站,使用粒子流程式設計控制制作一些效果, 如“粒子光環”
- 可參考以前作業
我選擇了第3個 ,制作粒子光環,步驟如下:
- 在場景中建立一個空對象,命名為ParticleHalo;
- 在ParticleHalo下建立一個Particle System子對象:添加元件->Effects->Particle System,命名為Halo;
-
建立C#腳本,命名為ParticleData.cs:
該腳本提供了一個儲存每個粒子資料的結構,分别對應其極坐标角度,半徑長,在半徑方向上遊離速度,運動方向(順時針/逆時針),代碼如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ParticleData : MonoBehaviour { public float angle = 0f; public float radius = 0f; public float speed = 0f; public bool clockwise = false; public ParticleData(float _angle,float _radius, float _speed, bool _clockwise) { angle = _angle; radius = _radius; speed = _speed; clockwise = _clockwise; } }
-
建立C#腳本,命名為ParticleHalo.cs:
初始化粒子大小、粒子生命周期和粒子數量;設定粒子系統參數,發射粒子;并将粒子發射到環的不同位置上,代碼如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ParticleHalo : MonoBehaviour { private ParticleSystem par_sys; private ParticleSystem.MainModule main; private ParticleSystem.Particle[] halo; private ParticleData[] par_data; public float size = 0.05f; //粒子大小 public float time = 9999f; //粒子生命周期 public int par_count = 10000; //粒子數量 // Start is called before the first frame update void Start() { halo = new ParticleSystem.Particle[par_count]; par_data = new ParticleData[par_count]; //初始化粒子系統 par_sys = this.GetComponent<ParticleSystem>(); main = par_sys.main; main.loop = false; main.startLifetime = time; main.startSpeed = 0f; main.startSize = size; main.maxParticles = par_count; par_sys.Emit(par_count); par_sys.GetParticles(halo); randomPlace(); } //随機放置粒子 private void randomPlace() { for (int i = 0; i < par_count; i++) { float r = Random.Range(5f, 12f); if (r % 3 == 1) r = Random.Range(7f, 10f); else if (r % 3 == 2) r = Random.Range(8f, 9f); float angle = Random.Range(0f, 360f); float theta = angle / 180 * Mathf.PI; float speed = Random.Range(0.5f, 1.5f); int flag = Random.Range(0, 2); bool clockwise = (flag == 0) ? false : true; halo[i].position = new Vector3(r * Mathf.Cos(theta), r * Mathf.Sin(theta), 0f); par_data[i] = new ParticleData(angle, r, speed, clockwise); } par_sys.SetParticles(halo, halo.Length); } // Update is called once per frame void Update() { for (int i = 0; i < par_count; i++) { if (par_data[i].clockwise) //順時針 par_data[i].angle -= Random.Range(0.01f, 0.5f); else //逆時針 par_data[i].angle += Random.Range(0.01f, 0.5f); par_data[i].angle %= 360f; float theta = par_data[i].angle / 180 * Mathf.PI; //粒子進行遊離 float r = par_data[i].radius; r += Mathf.PingPong(Time.time * par_data[i].speed, 2f); halo[i].position = new Vector3(r * Mathf.Cos(theta), r * Mathf.Sin(theta), 0); } par_sys.SetParticles(halo, halo.Length); } }
- 完成後将腳本ParticleHalo.cs挂載到Halo對象上,點選運作,效果如下:
-
可以看到已經初步實作了粒子光環,但效果不夠逼真,好像不是每個粒子在獨立運動,于是添加一個差分層變量tier,讓粒子角度的增量不都一樣。這個差分層變量使所有粒子分成了10個陣營,每個陣營角度增量不一樣。
同時還在後面添加了一個系數,這個系數和粒子的半徑關聯,使得離中心越遠的粒子角度增量越小,轉得越慢。
經過這個設定,粒子的運動顯得生動了許多(但圖檔效果看不太出來…😓)
最終結果
項目位址:
https://gitee.com/liuhz5/game-unity/tree/master/hw8