粒子系统是极好的系统,适应于各种各样的特效在游戏中,包括火焰,爆炸,烟雾,水,灯光,行星模拟,还有很多,unity伴随着一个建立在粒子系统上的library可以用来实施这些特效在你的或者3d游戏上,而且在unity上实施这个粒子系统有着额外的灵活性和允许你创造更神奇的特效,有时候你有些情况需要要求一些专用化,这些是不可以被建立的。此外,最近我尝试实现实现一个粒子效果让粒子分散开来像爆炸一样,然后停留在一个地方,最后缓慢的淡出不断循环。当粒子不断发散随着它们的生命周期可以熟练的用过build-in editor,等待它们的是终止。
这里可以看到一个粒子系统是我创建的,它使用build-in particle editor 在unity中:
暂停粒子系统
根据你们所看到的,它开始于一个随机放射方向的粒子系统,然后停止,,这个暂停特效比直着向前扩展要好,而且可以实现通过贴上一个代码在粒子系统中让它暂停然后继续
public class ParticleScript : MonoBehaviour {
public float timeToPause = 2.0f;
private ParticleSystem system;
private float time;
void Awake() {
system = GetComponent();
}
void Update() {
time += Time.deltaTime;
if (!system.isPaused && time > timeToPause) {
system.Pause();
}
}
}
public float timeToPause = 2.0f;
private ParticleSystem system;
private float time;
void Awake() {
system = GetComponent
}
void Update() {
time += Time.deltaTime;
if (!system.isPaused && time > timeToPause) {
system.Pause();
}
}
}
我们开始通过定义一个public float 叫做timeToPause 表示多长时间这个粒子应该持续播放在暂停之前,在Update中,我们update time和Time.deltaTime和暂停这个粒子系统用pause()在粒子系统本身上
这些都很简单并且好用,但是我们仍然需要修改粒子的颜色在暂停的视乎,这个主意是一旦粒子系统被暂停,他就开始衰退直到它消失不可见。
重新着色粒子
我们将要做的是重新着色每一个单独的粒子,因为他们可能有同样的颜色取决于你的粒子系统怎样被配置。在这个粒子中,我们将会修改粒子的alpha在衰退的部分,但你可以应用同样的方法在任何合成的颜色中。
第一件事我们要做的是引用到当前的粒子在系统中当我们暂停的时候:
public class ParticleScript : MonoBehaviour {
...
private ParticleSystem.Particle[] particles;
...
void Update() {
time += Time.deltaTime;
if (!system.isPaused && time > timeToPause) {
system.Pause();
particles = new ParticleSystem.Particle[system.particleCount];
system.GetParticles(particles);
}
}
}
...
private ParticleSystem.Particle[] particles;
...
void Update() {
time += Time.deltaTime;
if (!system.isPaused && time > timeToPause) {
system.Pause();
particles = new ParticleSystem.Particle[system.particleCount];
system.GetParticles(particles);
}
}
}
我们定义一个队列中的粒子项目我们将会用使用储存粒子当我们暂停了系统。我们然后初始化它与当前数量的粒子在系统中用system.particleCount来作用到一个缓冲区,然后前往有粒子储存的缓冲区队列中用system.GetParticles
现在我们可以反复处理和修改这些粒子根据这个队列。在Update中,我们将要添加一些逻辑当系统被暂停来重新着色粒子像这样:
public class ParticleScript : MonoBehaviour {
...
public float lifespan = 5.0f;
...
void Update() {
...
if (particles != null) {
for (int p = 0; p < particles.Length; p++) {
Color color = particles[p].startColor;
color.a = ((lifespan - time + timeToPause) / lifespan);
particles[p].startColor = color;
}
system.SetParticles(particles, particles.Length);
}
}
}
...
public float lifespan = 5.0f;
...
void Update() {
...
if (particles != null) {
for (int p = 0; p < particles.Length; p++) {
Color color = particles[p].startColor;
color.a = ((lifespan - time + timeToPause) / lifespan);
particles[p].startColor = color;
}
system.SetParticles(particles, particles.Length);
}
}
}
我们开始通过确定这个系统已经被暂停而且粒子已经被初始化,然后合并这些已经储藏的粒子当我们暂停这个系统的时候。对于单个粒子,我们抓住他们当前的颜色,并且更新alpha作为百分比的时间针对已经确认与总时间线对比过得粒子。同样需要注意的我们忽略了 timeToPause 添加到时间线来确认如何“淡出”之前的粒子
随着时间的推移这些粒子将会顺滑的淡出像这样:
表现
根
据这些粒子系统的数量,当你的粒子消散时,在每一个系统中的粒子,上面有一些规则有着基本的实施需要被标记,例如,你可能不想更新每一帧的粒子,而只更新
了第五帧,例如,你可能缓存当前的颜色,只更新粒子当这些变化非常重要时,列如,不要更新所有的粒子,在粒子系统中,当不同的alpha的差异是非常小的,甚至不会很明显。
如果你还想摧毁粒子系统,当它完全淡出识图(color.a <= 0f)而不是只是让它围绕。
这些表现的提升你选择的,如果有的话,将取决于你的案例,但是还是希望能给你一些启发对于一些特效你想要实现在你的游戏当中
完整的代码
最后,这里是完整的脚本,如下:
using UnityEngine;
using System.Collections;
public class ParticleScript : MonoBehaviour {
public float lifespan = 5.0f;
public float timeToPause = 2.0f;
private ParticleSystem.Particle[] particles;
private ParticleSystem system;
private float time;
void Awake() {
system = GetComponent();
}
void Update() {
time += Time.deltaTime;
if (!system.isPaused && time > timeToPause) {
system.Pause();
particles = new ParticleSystem.Particle[system.particleCount];
system.GetParticles(particles);
}
if (particles != null) {
for (int p = 0; p < particles.Length; p++) {
Color color = particles[p].startColor;
color.a = ((lifespan - time + timeToPause) / lifespan);
particles[p].startColor = color;
}
system.SetParticles(particles, particles.Length);
}
}
}
using System.Collections;
public class ParticleScript : MonoBehaviour {
public float lifespan = 5.0f;
public float timeToPause = 2.0f;
private ParticleSystem.Particle[] particles;
private ParticleSystem system;
private float time;
void Awake() {
system = GetComponent
}
void Update() {
time += Time.deltaTime;
if (!system.isPaused && time > timeToPause) {
system.Pause();
particles = new ParticleSystem.Particle[system.particleCount];
system.GetParticles(particles);
}
if (particles != null) {
for (int p = 0; p < particles.Length; p++) {
Color color = particles[p].startColor;
color.a = ((lifespan - time + timeToPause) / lifespan);
particles[p].startColor = color;
}
system.SetParticles(particles, particles.Length);
}
}
}
评论
发表评论