粒子系统
- 使用粒子流编程控制制作效果 “粒子海洋”+“粒子光环“
本次作业选择第三项,使用粒子流编程完成一些效果。粒子光环的制作在课上完成的粒子海洋的基础之上。
粒子光环的制作
添加GameObject->Particle System。分别命名为ParticleCirclefixed-x、ParticleCirclefixed-y、ParticleCircleSpread。Spread表示颜色加在粒子本身上,不管粒子如何运动其本身颜色不变,从视觉上看,随着粒子运动颜色实现了扩散;fixed表示颜色是按照位置显示的,即粒子在不同的坐标下颜色是不同的,从视觉上看,颜色是固定的。
设置初始位置和粒子系统属性如下。注意给不同的粒子系统对象添加了不同的tag,便于使用一份代码控制三个对象。
ParticleCirclefixed-x | ParticleCirclefixed-y | ParticleCircleSpread |
---|---|---|
代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75using UnityEngine;
using System.Collections;
public class ParticleCircle : MonoBehaviour
{
public ParticleSystem particleSystem;
private ParticleSystem.Particle[] particlesArray;
public int particleNumber = 4000;
public float radius = 4.0f;
public float[] particleAngle;
public float[] particleRadius;
public float maxR = 10f;
public float speed = 0.05f;
float time = 0;
public float free = 0.05f; //粒子浮动的范围
public Gradient colorGradient;
void Start()
{
//粒子系统的初始化设置
particleSystem = GetComponent<ParticleSystem>();
particlesArray = new ParticleSystem.Particle[particleNumber]; //初始化例子数组
particleSystem.maxParticles = particleNumber; //设置粒子最大数
particleAngle = new float[particleNumber];
particleRadius = new float[particleNumber];
particleSystem.Emit(particleNumber);
particleSystem.GetParticles(particlesArray);
//设置粒子初始位置
for (int i = 0; i < particleNumber; i++) {
float angle = Random.Range(0.0f, 360.0f); //随机角度
float rad = angle / 180 * Mathf.PI; //角度和弧度的转换
float midR = (maxR + radius) / 2;
//最大最小半径的随机缩放
float rate1 = Random.Range(1.0f, midR / radius);
float rate2 = Random.Range(midR / maxR, 1.0f);
float r = Random.Range(radius * rate1, maxR * rate2);
particleAngle[i] = angle;
particleRadius[i] = r;
particlesArray[i].position = new Vector3(r * Mathf.Cos(rad), r * Mathf.Sin(rad), 0.0f);//为每个粒子坐标赋值
//沿x轴上色 Spread
if(this.tag=="spread")
particlesArray[i].color = colorGradient.Evaluate((int)particlesArray[i].position.x);
}
particleSystem.SetParticles(particlesArray, particlesArray.Length);
}
void Update()
{
for (int i = 0; i < particleNumber; i++) {
if (i%2 == 0) {
particleAngle[i] += speed*(i%5+1);
} else {
particleAngle[i] -= speed*(i%5+1);
}
if (particleAngle[i] > 360)
particleAngle[i] -= 360;
if (particleAngle[i] < 0)
particleAngle[i] += 360;
particleRadius[i] += (Mathf.PingPong(time, free) - free/2.0f);
time += Time.deltaTime;
time %= 100;
float rad = particleAngle[i] / 180 * Mathf.PI;
particlesArray[i].position = new Vector3(particleRadius[i] * Mathf.Cos(rad), particleRadius[i] * Mathf.Sin(rad), 0f);
//沿x轴上色 fixed
if(this.tag=="fixed-x")
particlesArray[i].color = colorGradient.Evaluate((int)particlesArray[i].position.x);
//沿y轴上色 fixed
if(this.tag=="fixed-y")
particlesArray[i].color = colorGradient.Evaluate((int)particlesArray[i].position.y);
}
particleSystem.SetParticles(particlesArray, particleNumber);
}
}
- 将代码加载在三个粒子系统对象上,并设置参数
ParticleCirclefixed-x | ParticleCirclefixed-y | ParticleCircleSpread |
---|---|---|
运行效果
我们可以看出最大的粒子光环是fix-x,其次是fix-y,最小的是spread
粒子海洋的制作
粒子海洋的制作参考了翻译文章 Unity制作神奇的粒子海洋!
- 同粒子光环一样,首先添加粒子系统的游戏对象。并设置初始位置等属性
位置 | 粒子系统属性 |
---|---|
代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51using UnityEngine;
using System.Collections;
public class ParticleSea : MonoBehaviour {
public ParticleSystem particleSystem;
private ParticleSystem.Particle[] particlesArray;
public int seaResolution = 50;
public float spacing = 0.5f;
public float noiseScale = 0.2f;
public float heightScale = 3f;
private float perlinNoiseAnimX = 0.01f;
private float perlinNoiseAnimY = 0.01f;
public Gradient colorGradient;
void Start() {
particlesArray = new ParticleSystem.Particle[seaResolution * seaResolution];
particleSystem.maxParticles = seaResolution * seaResolution;
particleSystem.Emit(seaResolution * seaResolution);
particleSystem.GetParticles(particlesArray);
}
public void GetParticles(ParticleSystem.Particle[] particlesArray){
for(int i = 0; i<seaResolution; i++) {
for(int j = 0; j <seaResolution; j++) {
float zPos = Mathf.PerlinNoise(i * noiseScale, j * noiseScale) * heightScale;
particlesArray[i * seaResolution + j].position = new Vector3(i * spacing, zPos, j * spacing);
}
particleSystem.SetParticles (particlesArray, particlesArray.Length);
}
}
void Update() {
for(int i = 0; i<seaResolution; i++) {
for(int j = 0; j <seaResolution; j++) {
float zPos = Mathf.PerlinNoise(i * noiseScale + perlinNoiseAnimX, j * noiseScale + perlinNoiseAnimY) * heightScale;
particlesArray[i * seaResolution + j].color = colorGradient.Evaluate(zPos);
particlesArray[i * seaResolution + j].position = new Vector3(i * spacing, zPos, j * spacing);
}
}
perlinNoiseAnimX += 0.01f;
perlinNoiseAnimY += 0.01f;
particleSystem.SetParticles(particlesArray, particlesArray.Length);
}
}
将代码加载在粒子系统对象上,并设置参数
运行效果