要求
1、简单粒子制作
- 按参考资源要求,制作一个粒子系统,参考资源
- 使用 3.3 节介绍,用代码控制使之在不同场景下效果不一样
2、完善官方的“汽车尾气”模拟
- 使用官方资源资源 Vehicle 的 car, 使用 Smoke 粒子系统模拟启动发动、运行、故障等场景效果
3、参考 http://i-remember.fr/en 这类网站,使用粒子流编程控制制作一些效果, 如“粒子光环”
- 可参考以前作业
实现
模拟烟花粒子效果
这里不需要编程,完全通过面板设置实现一个烟花爆炸的效果。
模拟发射
首先创建一个空对象,给它挂载一个名为moveup的粒子系统,这是模拟烟花发射。
关闭粒子系统的Shape,更改Start Color为一个合适的颜色。
然后是Emission栏,这里就是控制粒子上升的部分。
最后为了拟真,设置粒子在上升过程中会闪光(先变亮,后变暗,最后爆炸即为消失)。这一步需要设置Size over Lifetime:
先变大后边小
完整设置窗口如下:
模拟爆炸
为了减少编程控制粒子运动的麻烦,可以偷懒再次创建一个对象,然后挂载一个粒子系统名为explosion,用于模拟爆炸。
首先将形状设置为Sphere,然后设置Radius设置为0.01,Radius Thickness设置为0,模拟烟花就在粒子中心爆炸。
然后就是Size over Lifetime,为了模拟爆炸后效果,设置一开始就显示颜色,然后随着爆炸扩散,颜色逐渐变浅直至消失:
完整窗口如下:
粒子光环
首先创建一个空对象,然后再给他挂上一个粒子系统
接下来就可以直接开始编程了,因为这个粒子光环的设置比较复杂,涉及到的很多变化过程是不能直接通过面板的设置来控制的,所以就干脆不用设置,全部用脚本控制。
设计的思路主要有两个部分。一是要初始化圆环,就是不考虑收缩时例子要在一个圆环中运动;二时控制粒子在运动时进行收缩,并且这个过程可以添加颜色的变换。
圆环运动
定义一个圆环类,用于控制运动。
class CirclePosition {
public float radius = 0f, angle = 0f, time = 0f;
public CirclePosition (float radius, float angle, float time) {
this.radius = radius;
this.angle = angle;
this.time = time;
}
}
初始化位置
void Start () {
// 初始化
particlesArray = new ParticleSystem.Particle[count];
circles = new CirclePosition[count];
particleSystem = gameObject.GetComponent<ParticleSystem> ();
particleSystem.maxParticles = count;
particleSystem.startSize = size;
particleSystem.Emit (count);
particleSystem.GetParticles (particlesArray);
float midRadius = (maxRadius + minRadius) / 2;
float minRate = Random.Range (1.0f, midRadius / minRadius);
float maxRate = Random.Range (midRadius / maxRadius, 1.0f);
for (int i = 0; i < count; i++) {
float radius = Random.Range (minRadius * minRate, maxRadius * maxRate);
float angle = (float) i / count * 360f;
float theta = angle / 180 * Mathf.PI;
// 设置粒子位置
circles[i] = new CirclePosition (radius, angle, (float) i / count * 360f);
particlesArray[i].position = new Vector3 (radius * Mathf.Cos (theta), radius * Mathf.Sin (theta), 0);
}
particleSystem.SetParticles (particlesArray, particlesArray.Length);
}
控制半径变化,颜色变化
这里通过调整半径变化,以达到一种“看起来”像是在运动的效果,并且在每次update时都调整颜色变换。
void Update () {
for (int i = 0; i < count; ++i) {
circles[i].angle = (circles[i].angle - Random.Range (0.4f, 0.6f) + 360f) % 360f;
float theta = circles[i].angle / 180 * Mathf.PI;
int f = count - (int)(Mathf.Pow(time / 5, 3) * count);
// 粒子半径变化
circles[i].time += Time.deltaTime;
circles[i].radius += Mathf.PingPong (circles[i].time / minRadius / maxRadius, range_m) - range_m / 2.0f;
if (circles[i].radius < minRadius) circles[i].radius += Time.deltaTime;
else if (circles[i].radius > maxRadius) circles[i].radius -= Time.deltaTime;
particlesArray[i].position = new Vector3 (circles[i].radius * Mathf.Cos (theta), circles[i].radius * Mathf.Sin (theta), 0);
//颜色
if (i < f)
particlesArray[i].startColor = gradient.Evaluate(0.5f);
else
{
float deep = circles[i].angle / 360f > 0.6f ? (circles[i].angle / 360f) : (circles[i].angle / 360f < 0.4f ? circles[i].angle / 360f : 0.4f); // 不允许全透明
particlesArray[i].startColor = gradient.Evaluate(deep);
}
}
particleSystem.SetParticles (particlesArray, particlesArray.Length);
}
效果展示
烟花:
粒子光环:
演示视频: https://www.bilibili.com/video/BV1Fv411b7G8/
完整项目:https://github.com/lurui7/3D-Game/tree/master/%E7%B2%92%E5%AD%90%E6%95%88%E6%9E%9C