介绍
参考 http://i-remember.fr/en 制作类似该网站效果
基本步骤
创建粒子光环(空对象)
将摄像机背景置为黑色
创建粒子系统,配置参数
新建 C# 脚本,命名为 ParticleRing
ParticleRing.cs
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
using System.Collections;using System.Collections.Generic;using UnityEngine; public class : MonoBehaviour{ public class circleParticle { public float radius = 0.0f; public float angle = 0.0f; public float time = 0.0f; public circleParticle(float radius, float angle, float time) { this.radius = radius; this.angle = angle; this.time = time; } } public ParticleSystem particleSystem; private ParticleSystem.Particle[] particlesArray; // 粒子数组 private circleParticle[] particleAttr; //粒子属性数组 public int particleSum = 10000; // 粒子数量 public float minRadius = 5.0f; public float maxRadius = 10.0f; public int Part = 2; // 将粒子们分为两部分 public float minSpeed = 0.09f; public float maxSpeed = 0.12f; public float speedLevelSum = 9; // 粒子速度分为九层 public float driftRange = 0.03f; // 游离范围 public Gradient colorGradient; void Start() { particleAttr = new circleParticle[particleSum]; particlesArray = new ParticleSystem.Particle[particleSum]; particleSystem.maxParticles = particleSum; particleSystem.Emit(particleSum); particleSystem.GetParticles(particlesArray); // 初始化梯度颜色控制器 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); for (int i = 0; i < particleSum; i++) { // 随机产生角度 float randomAngle = Random.Range(0.0f, 360.0f); // 随机产生每个粒子距离中心的半径,同时粒子要集中在平均半径附近 float midRadius = (maxRadius + minRadius) / 2; float minRate = Random.Range(1.0f, midRadius / minRadius); float maxRate = Random.Range(midRadius / maxRadius, 1.0f); float randomRadius = Random.Range(minRadius * minRate, maxRadius * maxRate); // 随机时间 float randomTime = Random.Range (0, 10f); //粒子属性设置 particleAttr[i] = new circleParticle(randomRadius, randomAngle, randomTime); particlesArray[i].position = new Vector3(randomRadius * Mathf.Cos(randomAngle), randomRadius * Mathf.Sin(randomAngle), 0.0f); } //设置粒子 particleSystem.SetParticles(particlesArray, particleSum); } void Update() { for (int i = 0; i < particleSum; i++) { // 速度方向分为两部分,一部分顺时针,一部分逆时针 float speed = (i % Part == 0) ? Random.Range(minSpeed, maxSpeed) : - 2 * Random.Range(minSpeed, maxSpeed); // 给不同的粒子速度加权,分为 9 层 float weightedSpeed = (i % speedLevelSum + 1) * speed; // 更新角度 particleAttr[i].angle += Mathf.Sqrt(2 * particleAttr [i].radius / maxRadius) * weightedSpeed; // 此处粒子的速度与半径的平方根成正比 particleAttr[i].angle = particleAttr[i].angle % 360; float radian = particleAttr[i].angle / 180 * Mathf.PI; // 更新半径 particleAttr [i].time += Time.deltaTime; particleAttr [i].radius += Mathf.PingPong(particleAttr [i].time / minRadius / maxRadius, driftRange) - driftRange / 2.0f; // 更新位置 particlesArray[i].position = new Vector3(particleAttr [i].radius * Mathf.Cos(radian), particleAttr [i].radius * Mathf.Sin(radian), 0f); particlesArray[i].color = colorGradient.Evaluate(particleAttr[i].angle / 360.0f); } particleSystem.SetParticles(particlesArray, particleSum); }} |
效果图
鼠标悬停在粒子光环内部效果
修改 circleParticle
类
添加 originRadius
,用以记录光环收缩前当前粒子的旋转半径
1234567891011121314 |
public class circleParticle{ public float radius = 0.0f; public float angle = 0.0f; public float time = 0.0f; public float originRadius = 0.0f; public circleParticle(float radius, float angle, float time) { this.radius = radius; this.angle = angle; this.time = time; this.originRadius = radius; }} |
修改 update()
判断鼠标与光环的关系
123456789101112131415 |
// 鼠标到光环中心的距离float mouseToCenter = Mathf.Sqrt (Mathf.Pow((Input.mousePosition.x - Screen.width / 2), 2f) + Mathf.Pow((Input.mousePosition.y - Screen.height / 2), 2f));// 鼠标在光环内部bool mouseInRing = false;// 此处认为满足此条件,即是在光环内部if (mouseToCenter < Screen.height / 4) { mouseInRing = true; if (mouseInRingTime <= mouseInRingTimeLimit) { // 在粒子光环里面的累计时间每一帧加一,并不会大过限定值 mouseInRingTime++; }} else { // 鼠标移出粒子光环 mouseInRing = false; if (mouseInRingTime > 0) mouseInRingTime--;} |
根据鼠标与光环关系进行的行为
123456789101112131415161718192021222324 |
// 当鼠标在粒子光环里当时间累积为零if (mouseInRingTime == 0) { particleAttr [i].originRadius = particleAttr[i].radius;} // 鼠标进入粒子光环if (mouseInRing){ particleAttr[i].angle -= 1 / 3 * Mathf.Sqrt(2 * particleAttr [i].radius / maxRadius) * weightedSpeed; // 此处粒子的速度与半径的平方根成正比 particleAttr[i].angle = particleAttr[i].angle % 360; radian = particleAttr[i].angle / 180 * Mathf.PI; if (mouseInRingTime < mouseInRingTimeLimit) { particleAttr [i].radius = minRadius + (particleAttr [i].radius - minRadius) * (particleAttr [i].radius / maxRadius); }}// 鼠标在粒子光环外if (!mouseInRing && mouseInRingTime > 0){ particleAttr[i].angle += mouseInRingTime / 5 * Mathf.Sqrt(2 * particleAttr [i].radius / maxRadius) * weightedSpeed; // 此处粒子的速度与半径的平方根成正比 particleAttr[i].angle = particleAttr[i].angle % 360; radian = particleAttr[i].angle / 180 * Mathf.PI; particleAttr [i].radius += (particleAttr [i].originRadius - particleAttr [i].radius) / Mathf.Sqrt(mouseInRingTime) * (particleAttr [i].radius / maxRadius);} |
完整代码
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
using System.Collections;using System.Collections.Generic;using UnityEngine; public class : MonoBehaviour{ public class circleParticle { public float radius = 0.0f; public float angle = 0.0f; public float time = 0.0f; public float originRadius = 0.0f; public circleParticle(float radius, float angle, float time) { this.radius = radius; this.angle = angle; this.time = time; this.originRadius = radius; } } public ParticleSystem particleSystem; private ParticleSystem.Particle[] particlesArray; // 粒子数组 private circleParticle[] particleAttr; //粒子属性数组 public int particleSum = 10000; // 粒子数量 public float minRadius = 5.0f; public float maxRadius = 10.0f; public int Part = 2; // 将粒子们分为两部分 public float minSpeed = 0.09f; public float maxSpeed = 0.12f; public float speedLevelSum = 9; // 粒子速度分为九层 public float driftRange = 0.03f; // 游离范围 public int mouseInRingTime; public int mouseInRingTimeLimit; public Gradient colorGradient; void Start() { particleAttr = new circleParticle[particleSum]; particlesArray = new ParticleSystem.Particle[particleSum]; particleSystem.maxParticles = particleSum; particleSystem.Emit(particleSum); particleSystem.GetParticles(particlesArray); // 初始化梯度颜色控制器 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); mouseInRingTime = 0; mouseInRingTimeLimit = 30; for (int i = 0; i < particleSum; i++) { // 随机产生角度 float randomAngle = Random.Range(0.0f, 360.0f); // 随机产生每个粒子距离中心的半径,同时粒子要集中在平均半径附近 float midRadius = (maxRadius + minRadius) / 2; float minRate = Random.Range(1.0f, midRadius / minRadius); float maxRate = Random.Range(midRadius / maxRadius, 1.0f); float randomRadius = Random.Range(minRadius * minRate, maxRadius * maxRate); // 随机时间 float randomTime = Random.Range (0, 10f); //粒子属性设置 particleAttr[i] = new circleParticle(randomRadius, randomAngle, randomTime); particlesArray[i].position = new Vector3(randomRadius * Mathf.Cos(randomAngle), randomRadius * Mathf.Sin(randomAngle), 0.0f); } //设置粒子 particleSystem.SetParticles(particlesArray, particleSum); } void Update() { // 鼠标到光环中心的距离 float mouseToCenter = Mathf.Sqrt (Mathf.Pow((Input.mousePosition.x - Screen.width / 2), 2f) + Mathf.Pow((Input.mousePosition.y - Screen.height / 2), 2f)); // 鼠标在光环内部 bool mouseInRing = false; // 此处认为满足此条件,即是在光环内部 if (mouseToCenter < Screen.height / 4) { mouseInRing = true; if (mouseInRingTime <= mouseInRingTimeLimit) { // 在粒子光环里面的累计时间每一帧加一,并不会大过限定值 mouseInRingTime++; } } else { // 鼠标移出粒子光环 mouseInRing = false; if (mouseInRingTime > 0) mouseInRingTime--; } for (int i = 0; i < particleSum; i++) { // 速度方向分为两部分,一部分顺时针,一部分逆时针 float speed = (i % Part == 0) ? Random.Range(minSpeed, maxSpeed) : - 2 * Random.Range(minSpeed, maxSpeed); // 给不同的粒子速度加权,分为 9 层 float weightedSpeed = (i % speedLevelSum + 1) * speed; // 更新角度 particleAttr[i].angle += Mathf.Sqrt(2 * particleAttr [i].radius / maxRadius) * weightedSpeed; // 此处粒子的速度与半径的平方根成正比 particleAttr[i].angle = particleAttr[i].angle % 360; float radian = particleAttr[i].angle / 180 * Mathf.PI; // 更新半径 particleAttr [i].time += Time.deltaTime; particleAttr [i].radius += Mathf.PingPong(particleAttr [i].time / minRadius / maxRadius, driftRange) - driftRange / 2.0f; // 当鼠标在粒子光环里当时间累积为零 if (mouseInRingTime == 0) { particleAttr [i].originRadius = particleAttr[i].radius; } // 鼠标进入粒子光环 if (mouseInRing) { particleAttr[i].angle -= 1 / 3 * Mathf.Sqrt(2 * particleAttr [i].radius / maxRadius) * weightedSpeed; // 此处粒子的速度与半径的平方根成正比 particleAttr[i].angle = particleAttr[i].angle % 360; radian = particleAttr[i].angle / 180 * Mathf.PI; if (mouseInRingTime < mouseInRingTimeLimit) { particleAttr [i].radius = minRadius + (particleAttr [i].radius - minRadius) * (particleAttr [i].radius / maxRadius); } } // 鼠标在粒子光环外 if (!mouseInRing && mouseInRingTime > 0) { particleAttr[i].angle += mouseInRingTime / 5 * Mathf.Sqrt(2 * particleAttr [i].radius / maxRadius) * weightedSpeed; // 此处粒子的速度与半径的平方根成正比 particleAttr[i].angle = particleAttr[i].angle % 360; radian = particleAttr[i].angle / 180 * Mathf.PI; particleAttr [i].radius += (particleAttr [i].originRadius - particleAttr [i].radius) / Mathf.Sqrt(mouseInRingTime) * (particleAttr [i].radius / maxRadius); } // 更新位置 particlesArray[i].position = new Vector3(particleAttr [i].radius * Mathf.Cos(radian), particleAttr [i].radius * Mathf.Sin(radian), 0f); particlesArray[i].color = colorGradient.Evaluate(particleAttr[i].angle / 360.0f); } particleSystem.SetParticles(particlesArray, particleSum); }} |
最终效果
引用
Unity3D学习笔记(9)—— 粒子光环
Unity-3D 粒子光圈效果
原文地址:https://www.cnblogs.com/chinatrump/p/11615073.html
时间: 2024-10-05 21:01:54