粒子效果(Lab 9)

来源:互联网 发布:金蝶软件多少钱一套 编辑:程序博客网 时间:2024/06/03 20:48

阅读“Unity制作神奇的粒子海洋!” 点击打开链接

参考点击打开链接制作类似该网站的效果。

该参考网站的粒子效果:


于是,我们的目标就是利用Unity实现相似的粒子效果。


我们可以观察到:

1. 粒子的分布主要是一个环状;

2. 粒子的明暗分布是不均匀的;

3. 粒子的运动轨迹是顺时针和逆时针混合的;

4. 粒子并没有一个严格的圆形运动轨迹,每个粒子几乎都是散乱的随其他粒子一起,做圆形运动。

于是,我们可以考虑在一个空对象下,建立我们的粒子系统,并利用程序来控制粒子运动。


步骤一

创建空对象,在该对象中添加组件->Effect->Particle System


步骤二

创建C#文件CirclePosition,来记录粒子运动轨迹的半径,目前运动的角度,以及运动的时间。
public 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;       // 时间  }}

步骤三

接下来就是粒子运动的关键部分,创建C#文件Particle,来控制粒子的各项信息,包括大小,数量,运动速度,运动方向等
我们以实现顺时针方向运动的粒子运动为例,首先,我们利用公有变量来设置粒子的大小、半径等基本信息:
private ParticleSystem particleSystem;  // 粒子系统private ParticleSystem.Particle[] Arrye;  // 粒子数组private CirclePosition[] circlePosition;public int count = 10000;       // 粒子数量public float size = 0.05f;      // 粒子大小public float minRadius = 5.0f;  // 粒子旋转最小半径public float maxRadius = 10.0f; // 粒子旋转最大半径public float speed = 2f;        // 速度

初始化之后,我们需要随机分布这些粒子:
void ParticleRandom() {  for (int i = 0; i < count; ++i) {// 随机设置每个粒子的运动轨迹半径,同时保证粒子在带状分布的范围内,中间多,两边少float midRadius = (maxRadius + minRadius) / 2;  float minRate = Random.Range(1.0f, midRadius / minRadius);  float maxRate = Random.Range(midRadius / maxRadius, 1.0f);  float radius = Random.Range(minRadius * minRate, maxRadius * maxRate);  // 在0-360°之间随机分配每个粒子的角度float angle = Random.Range(0.0f, 360.0f);// 随机每个粒子的游离起始时间float time = Random.Range(0.0f, 60.0f);circlePosition[i] = new CirclePosition(radius, angle, time);float theta = angle / 180 * Mathf.PI;Arrye[i].position = new Vector3(circlePosition[i].radius * Mathf.Cos(theta), 0f, circlePosition[i].radius * Mathf.Sin(theta));  }particleSystem.SetParticles(Arrye, Arrye.Length);}

这时候,只要在每次调用update函数时,改变每个粒子的angle,就可以使粒子动起来。
(一个值得注意的问题是,要保证粒子的angle一直保持在360°范围之内)
void Update () {int differentiate = 2;for (int i = 0; i < count; i++) {circlePosition[i].angle -= 0.1f;  // 保证angle在0~360度  circlePosition[i].angle = (360.0f + circlePosition[i].angle) % 360.0f;float theta = circlePosition[i].angle / 180 * Mathf.PI;  Arrye[i].position = new Vector3(circlePosition[i].radius * Mathf.Cos(theta), 0f, circlePosition[i].radius * Mathf.Sin(theta));}particleSystem.SetParticles(Arrye, Arrye.Length);}

这时,我们将文件挂载在添加了ParticleSystem组件的空对象上,为了便于观察我设置了两种颜色的粒子系统,分别设置粒子数量和分布范围等:



观察效果:

可见已经基本完成了实验要求,但现在这些粒子的运动太过死板。

步骤四

解决运动太多死板的问题,我们可以在update中给每一个粒子一个不同的角度增量:
int differentiate = 2;for (int i = 0; i < count; i++) {circlePosition[i].angle -= (i % differentiate + 1) * (speed / circlePosition[i].radius / differentiate); 

然后利用PingPong方法,让粒子不是沿着标准的半径移动,而是在一定程度的波动范围内移动:
首先添加共有变量pingPong来规范游离范围:
public float pingPong = 0.01f;  // 游离范围

然后在update中更新每个粒子的角度增量:
circlePosition[i].time += Time.deltaTime;  circlePosition[i].radius += Mathf.PingPong(circlePosition[i].time / minRadius / maxRadius, pingPong) - pingPong / 2.0f;

观察结果:


0 0
原创粉丝点击