实践内容
参考 http://i-remember.fr/en 这类网站,使用粒子流编程控制制作一些效果, 如“粒子光环”
参考博客
步骤
-
添加:粒子系统
在 Hierarchy下,Effects →添加 Particle System,命名为ParticleHalo
-
粒子系统脚本
1) 新建ParticleHalo.cs 脚本
2) 构建粒子结构体,记录粒子的半径、角度和时间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; // 时间 } }
3) 设置需要用到的变量
- 声明操作对象:包括粒子系统、粒子数组、粒子对应位置的数组CirclePosition
private ParticleSystem particleSys; // 粒子系统 private ParticleSystem.Particle[] particleArr; // 粒子数组 private CirclePosition[] circle; // 极坐标数组
- 声明粒子属性:数量、粒子大小、旋转的最大最小半径、旋转方向、旋转速度、粒子游离范围,从而可以控制光环的显示效果
public int count = 10000; // 粒子数量 public float size = 0.10f; // 粒子大小 public float minRadius = 5.0f; // 最小半径 public float maxRadius = 12.0f; // 最大半径 public bool clockwise = true; // 顺时针|逆时针 public float speed = 2f; // 速度 public float pingPong = 0.02f; // 游离范围
4)粒子系统初始化和启动
- 根据设置的数量count来初始化粒子数组和粒子位置数组
- 设置粒子大小和初速度,以及粒子最大数量
- 发射粒子,并将粒子随机分布在圆环上
void Start() { // 初始化粒子数组 particleArr = new ParticleSystem.Particle[count]; circle = new CirclePosition[count]; // 初始化粒子系统 particleSys = this.GetComponent<ParticleSystem>(); particleSys.startSpeed = 0; // 粒子位置由程序控制 particleSys.startSize = size; // 设置粒子大小 particleSys.loop = false; particleSys.maxParticles = count; // 设置最大粒子量 particleSys.Emit(count); // 发射粒子 particleSys.GetParticles(particleArr); RandomlySpread(); // 初始化各粒子位置 }
粒子随机分布函数
void RandomlySpread() { 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); // 随机每个粒子的角度 float angle = Random.Range(0.0f, 360.0f); float theta = angle / 180 * Mathf.PI; // 随机每个粒子的游离起始时间 float time = Random.Range(0.0f, 360.0f); circle[i] = new CirclePosition(radius, angle, time); particleArr[i].position = new Vector3(circle[i].radius * Mathf.Cos(theta), 0f, circle[i].radius * Mathf.Sin(theta)); } particleSys.SetParticles(particleArr, particleArr.Length); }
5)粒子系统旋转
改变例子角度可以实现粒子的旋转,使旋转效果更加明显,可以给粒子的旋转添加灵活性- 为每个粒子设置不同的角速度:根据粒子索引分为不同的组,不同组的速度变化量不同
- 允许粒子在一定半径范围内游离:利用数学库中的PingPong函数实现粒子运动的半径在一定范围内来回变动
void Update() { for (int i = 0; i < count; i++) { if (clockwise) // 顺时针旋转 circle[i].angle -= (i % tier + 1) * (speed / circle[i].radius / tier); else // 逆时针旋转 circle[i].angle += (i % tier + 1) * (speed / circle[i].radius / tier); // 保证angle在0~360度 circle[i].angle = (360.0f + circle[i].angle) % 360.0f; float theta = circle[i].angle / 180 * Mathf.PI; particleArr[i].position = new Vector3(circle[i].radius * Mathf.Cos(theta), 0f, circle[i].radius * Mathf.Sin(theta)); // 粒子在半径方向上游离 circle[i].time += Time.deltaTime; circle[i].radius += Mathf.PingPong(circle[i].time / minRadius / maxRadius, pingPong) - pingPong / 2.0f; particleArr[i].color = colorGradient.Evaluate(circle[i].angle / 360.0f); } particleSys.SetParticles(particleArr, particleArr.Length); }
6) 添加光效
添加Gradient类,设置粒子颜色动态变化。在Update中让粒子颜色根据旋转角度产生一个变化public Gradient colorGradient;//添加Gradient变量 particleArr[i].color = colorGradient.Evaluate(circle[i].angle / 360.0f);
-
显示设置
在ParticleHalo的Inspector面板下,点击脚本ParticleHalo/Color Gradient,进行如下设置
设置相机Transform 和 Clear Flags(将背景设为黑色)
运行
-
使粒子变亮
这里的粒子亮度太暗,我们可以改变粒子大小或更换一个更亮的粒子材质,使显示效果更好
- 设置粒子大小size 为0.1,运行
结果
- 或者导入ParticleSystem资源包
右键Assert → Import Package → ParticleSystems
选中Particlehalo物体,在Inspector下,展开Particle System → 展开Renderer → 点击Material选项按钮 → 更换为ParticleFirecloud的材质
size设为0.05
运行结果
6. 再添加一个粒子系统作为内环
create Effect → 添加ParticleSystem,命名为Anticlochwise_inner,添加ParticleHalo.cs脚本
调整参数
结果
视频