作業與練習
本次作業基本要求是三選一- 1、簡單粒子製作,按參考資源要求,製作一個粒子系統,參考資源使用 3.3 節介紹,用代碼控制使之在不同場景下效果不一樣
- 2、完善官方的“汽車尾氣”模擬,使用官方資源資源 Vehicle 的 car, 使用 Smoke 粒子系統模擬啓動發動、運行、故障等場景效果
- 3、參考 http://i-remember.fr/en 這類網站,使用粒子流編程控制製作一些效果, 如“粒子光環”可參考以前作業
粒子光環
我在這裏做的是粒子光環。
首先是創建一個叫ParticleHalo的類,在開始編寫其內容之前首先需要一個輔助的類,這個類是用來進行定位的類,叫做CirclePosition。
public class CirclePosition
{
public float radius = 0f, angle = 0f, time = 0f;
public CirclePosition(float radius, float angle, float time)
{
this.angle = angle; // 角度
this.radius = radius; // 半徑
this.time = time; // 時間
}
}
有了CirclePosition之後我們開始編寫ParticleHalo的內容。
首先是建立其變量,是用來定義粒子的各個屬性的。
//設置粒子的各個屬性
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;
然後在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);
RandomlyPos();
}
然後我們使用RandomlyPos將所有的粒子隨機分佈在圓圈軌道上。
void RandomlyPos()
{
for (int i = 0; i < count; ++i)
{
float midRadius = (maxRadius + minRadius) / 2;
float radius = (float)normalGenerator.NextGaussian(midRadius, 0.7);//使用高斯分佈
float angle = Random.Range(0.0f, 360.0f);
float theta = angle / 180 * Mathf.PI;
float time = Random.Range(0.0f, 360.0f);
float radiusChange = Random.Range(0.0f, maxRadiusChange);
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);
}
然後讓粒子旋轉起來,這個內容在update裏面實現。
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);
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].startColor = startColor;
circle[i].time += Time.deltaTime;
circle[i].radius += Mathf.PingPong(circle[i].time / minRadius / maxRadius, maxRadiusChange) - maxRadiusChange / 2.0f;
}
particleSys.SetParticles(particleArr, particleArr.Length);
}