本博客参考 i-remember.fr 这类网站,使用粒子流编程控制制作了一些效果,参考了一些师兄的代码,最后实现的效果还是很好看的
效果如图:图片为静态,实际的动态效果感觉不错,类似老师说的粒子光环
实现过程:
1、添加粒子系统
先在界面中加入一个空白对象,增加两个子对象,子对象下添加粒子系统:
2、添加脚本
首先在脚本中定义一些需要用到的数据:
private ParticleSystem particleSys;
private ParticleSystem.Particle[] particles;
private CirclePosition[] circles;
private int tier = 10;
public Gradient colorGradient;
public int count = 10000;
// 粒子数量
public float size = 0.03f;
// 粒子大小
public float minRadius = 5.0f;
// 最小半径
public float maxRadius = 12.0f;
// 最大半径
public bool clockwise = true;
// 顺时针|逆时针
public float speed = 2f;
// 速度
public float pingPong = 0.02f;
// 游离范围
接下来在start中,初始化粒子的位置和渐变颜色:
void Start () {
particles = new ParticleSystem.Particle[count];
circles = new CirclePosition[count];
//初始化粒子系统
particleSys = this.GetComponent<ParticleSystem>();
particleSys.startSpeed = 0;
particleSys.startSize = size;
particleSys.loop = false;
particleSys.maxParticles = count; // 设置最大粒子量
particleSys.Emit(count); // 发射粒子
particleSys.GetParticles(particles);
//初始化颜色
GradientAlphaKey[] alphaKeys = new GradientAlphaKey[5];
alphaKeys[0].time = 0.0f;
alphaKeys[0].alpha = 1.0f;
alphaKeys[1].time = 0.4f;
alphaKeys[1].alpha = 0.4f;
alphaKeys[2].time = 0.6f;
alphaKeys[2].alpha = 1.0f;
alphaKeys[3].time = 0.9f;
alphaKeys[3].alpha = 0.4f;
alphaKeys[4].time = 1.0f;
alphaKeys[4].alpha = 0.9f;
GradientColorKey[] colorKeys = new GradientColorKey[2];
colorKeys[0].time = 0.0f;
colorKeys[0].color = Color.white;
colorKeys[1].time = 1.0f;
colorKeys[1].color = Color.white;
colorGradient.SetKeys(colorKeys, alphaKeys);
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);
circles[i] = new CirclePosition(radius, angle, time);
particles[i].position = new Vector3(circles[i].radius * Mathf.Cos(theta), circles[i].radius * Mathf.Sin(theta), 0f);
}
particleSys.SetParticles(particles, particles.Length);
}
这里涉及到了另外一个类——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;
}
}
最后要让粒子转动起来,应该在最开始的ParticleHalo类的Update函数中实现:
// Update is called once per frame
void Update()
{
for (int i = 0; i < count; i++)
{
if (clockwise)
circles[i].angle -= (i % tier + 1) * (speed / circles[i].radius / tier);
else
circles[i].angle += (i % tier + 1) * (speed / circles[i].radius / tier);
circles[i].time += Time.deltaTime;
circles[i].radius += Mathf.PingPong(circles[i].time / minRadius / maxRadius, pingPong) - pingPong / 2.0f;
circles[i].angle = (360.0f + circles[i].angle) % 360.0f;
float theta = circles[i].angle / 180 * Mathf.PI;
particles[i].position = new Vector3(circles[i].radius * Mathf.Cos(theta), circles[i].radius * Mathf.Sin(theta), 0f);
particles[i].color = colorGradient.Evaluate(circles[i].angle / 360.0f);
}
particleSys.SetParticles(particles, particles.Length);
}
最后一步就是将脚本挂在两个粒子系统上,注意到,在脚本中定义了一个clockwise的变量,可以选择粒子转动的方向,将一个粒子系统定义为顺时针旋转,另一个粒子系统定义为逆时针旋转,就完成了制作了。
3、设置天空盒
由于粒子系统的亮度比较低,所以需要一个比较暗的背景或者反差比较大的背景,这里我是在Assets Store中下载了一个天空盒,效果如下:
最后效果:
视频:粒子光环。。。。-其他-高清完整正版视频在线观看-优酷 (youku.com)
代码地址:3d-game/粒子光环/ParticleHalo at main · wujf37/3d-game (github.com)
本博客对粒子效果的实现有了一些尝试,通过对文章的学习掌握了一些粒子流编程,对老师没有要求必做的任务进行了一些尝试,最后实现的效果尚可,同时之前也完成了老师要求奖励的部分—
(奖励)编写《Unity制作神奇的粒子海洋!》教程,在bilibili发布
教程链接如下:Unity3d神奇的粒子海洋 - 哔哩哔哩