作业与练习
本次作业基本要求是三选一- 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);
}