作业要求:
本次作业基本要求是三选一,选择第三个:
参考http://i-remember.fr/en 这类网站,使用粒子流编程制作一些效果,如“粒子光环”
参考师兄博客
实现效果
实现过程
新建对象
新建空对象ParticleHalo,给particleHalo新建两个空对象,并添加Particle System组件

代码
新建
新建ParticleData类,用来实现粒子效果
1 2 3 4 5 6 7 8 9 10
| public class ParticleData { public float radius, angle, time; public ParticleData(float radius_,float angle_,float time_) { radius = radius_; angle = angle_; time = time_; } }
|
再定义一个粒子系统的变量,存储对应数据
1 2 3
| private ParticleSystem particleSys; private ParticleSystem.Particle[] particleArray; private ParticleData[] particleData;
|
公有成员可以在界面上直接调控
1 2 3 4 5 6 7
| public int count = 10000; public float size = 0.03f; public float minRadius = 6.0f; public float maxRadius = 10.0f; public bool clockwise = true; public float speed = 2f; public float pingPong = 0.02f;
|
初始化
Start函数进行初始化,主要是对粒子系统进行实例化,相当于在界面里调整各种属性
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
| private void Start() {
particleArray = new ParticleSystem.Particle[count]; particleData = new ParticleData[count];
particleSys = this.GetComponent<ParticleSystem>(); particleSys.startSpeed = 0; particleSys.startSize = size; particleSys.loop = false; particleSys.maxParticles = count; particleSys.Emit(count); particleSys.GetParticles(particleArray);
setParticlePosition(); }
void setParticlePosition() { float midRadius, minRate, maxRate, radius,angle,theta,time;
for (int i = 0; i < count; i++) { midRadius = (maxRadius + minRadius) / 2; minRate = Random.Range(1.0f, midRadius / minRadius); maxRate = Random.Range(midRadius / maxRadius, 1.0f); radius = Random.Range(minRadius * minRate, maxRadius * maxRate); angle = Random.Range(0.0f, 360.0f); theta = angle / 180 * Mathf.PI; time = Random.Range(0.0f, 360.0f);
particleData[i] = new ParticleData(radius,angle,time); particleArray[i].position = new Vector3(particleData[i].radius * Mathf.Cos(theta), particleData[i].radius * Mathf.Sin(theta),0f); } particleSys.SetParticles(particleArray, particleArray.Length); }
|
运动
让每个粒子的角度在每一帧都减少或增加一个值就可以实现旋转,价格速度差分层数让不同层的粒子旋转的速度不一样
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| private int diff = 10; private void Update() { float theta; for (int i = 0; i < count; i++) { if (clockwise) { particleData[i].angle -= (i % diff + 1) * (speed / particleData[i].radius / diff); } else { particleData[i].angle += (i % diff + 1) * (speed / particleData[i].radius / diff); } particleData[i].angle = (360.0f + particleData[i].angle) % 360.0f; theta = particleData[i].angle / 180 * Mathf.PI; particleArray[i].position = new Vector3(particleData[i].radius * Mathf.Cos(theta), particleData[i].radius * Mathf.Sin(theta), 0f); } particleSys.SetParticles(particleArray, particleArray.Length); }
|
设置粒子的跳动效果,让其在这个半径的附近进行“浮游”。主要是运用PingPong算法:
Update函数中在确定particleArr [i]的位置之前,对运动半径进行处理:
1 2
| particleData[i].time += Time.deltaTime; particleData[i].radius += Mathf.PingPong(particleData[i].time / minRadius / maxRadius, pingPong) - pingPong / 2.0f;
|
透明度和颜色
加入新的公有成员:
1
| public Gradient colorGradient;
|
在inspector窗口里改变colorGradient的值

start函数进行颜色初始化
1 2 3 4 5 6 7 8 9 10 11 12 13
| void changeColor() { float colorValue; for (int i = 0; i < count; i++) { colorValue = (Time.realtimeSinceStartup - Mathf.Floor(Time.realtimeSinceStartup)); colorValue += particleData[i].angle/360; while (colorValue > 1) colorValue--; particleArray[i].color = colorGradient.Evaluate(colorValue); } }
|
在Update函数的for循环里加上执行改变函数的语句

项目地址
Github
演示视频
bilibili