パーティクルシステム

3Dパーティクルシステムのゲームを学ぶ、参照I-覚えて、上のハローの例行うことにしました。手を開始する前に、注意深い観察を必要とするが、ハロ二つの層、一つの層をさらに時計回りに回転し、反時計回り、中間部と大粒子を発見し、粒子間の同じハロで自由に回転するであろう。

ベース準備

2つの、新しいParticleCircleスクリプトをパーティクルシステムコンポーネントを追加し、子オブジェクトの上にマウントするために、時計回りと反時計回りにサブオブジェクト構築するための新しい空のオブジェクトParticleCircle、:

      
      
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
      
      
使用して UnityEngineを。
使用 にSystem.Collectionsを。
パブリック クラス CirclePosition
{
公共 フロート 半径= 0F 、角度= 0F 、時間= 0F
パブリック フロート半径、フロート角、フロート時間)
{
この .radius =半径。
この .angle =角度;
この .time =時間;
}
}
パブリック クラス ParticleCircle:MonoBehaviour {
private ParticleSystem particleSys; // 粒子系统
private ParticleSystem.Particle[] particleArr;
private CirclePosition[] circle; // 极坐标数组
public int count = 10000; // 粒子数量
public float size = 3f; // 粒子大小
public float minRadius = 4.0f; // 最小半径
public float maxRadius = 8.0f; // 最大半径
public bool clockwise = true; // 顺时针|逆时针
public float speed = 2f; // 速度
public float pingPong = 0.02f; // 游离范围
private int tier = 10; // 速度差分层数
public Gradient colorGradient; // 颜色控制
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);
}
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(); // 初始化各粒子位置
}

旋转粒子

在Update函数里逐渐改变粒子的角度使粒子旋转,其中tier使粒子角度改变量不一致,这样粒子旋转就不会看起来像是图片在旋转:

      
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
      
      
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);
circle[i].angle = ( 360.0f + circle[i].angle)% 360.0f; // 保证angle在0~360度
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));
}
particleSys.SetParticles(particleArr, particleArr.Length);
}

游离粒子

Unity的Mathf的PingPong函数使得值在范围内来回变动,使用它让粒子半径来回变动。以下添加到Update函数中:

      
      
1
2
      
      
circle[i].time += Time.deltaTime;
circle[i].radius += Mathf.PingPong(circle[i].time / minRadius / maxRadius, pingPong) - pingPong / 2.0f;

添加透明度

仔细观察i-remember会发现不同地方亮度不同,也可以说是透明度不同,使用Gradient类可以解决这个问题。一下添加到start函数中:

      
      
1
2
3
4
5
6
7
8
9
10
      
      
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;
大专栏   粒子系统 class="line">colorGradient.SetKeys(colorKeys, alphaKeys);

然后在Update中根据粒子的角度改变粒子的透明度:

      
      
1
      
      
particleArr[i].color = colorGradient.Evaluate(circle[i].angle / 360.0f);

修改参数

修改主摄像机到合适位置:

另外一层是逆时针旋转的,因此把clockwise的勾去掉,同时修改参数直到效果满意:

完整代码

      
      
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
      
      
using UnityEngine;
using System.Collections;
public class CirclePosition
{
public float radius = 0f, angle = 0f, time = 0f;
public (float radius, float angle, float time)
{
this.radius = radius;
this.angle = angle;
this.time = time;
}
}
public class ParticleCircle : MonoBehaviour {
private ParticleSystem particleSys; // 粒子系统
private ParticleSystem.Particle[] particleArr;
private CirclePosition[] circle; // 极坐标数组
public int count = 10000; // 粒子数量
public float size = 3f; // 粒子大小
public float minRadius = 4.0f; // 最小半径
public float maxRadius = 8.0f; // 最大半径
public bool clockwise = true; // 顺时针|逆时针
public float speed = 2f; // 速度
public float pingPong = 0.02f; // 游离范围
private int tier = 10; // 速度差分层数
public Gradient colorGradient; // 颜色控制
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);
}
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(); // 初始化各粒子位置
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);
}
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);
circle[i].angle = ( 360.0f + circle[i].angle)% 360.0f; // 保证angle在0~360度
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] = colorGradient.Evaluate .color(サークル[I] .angle / 360.0f); //角度に応じて透明度を変更します
}
particleSys.SetParticles(particleArr、particleArr.Length)。
}
}

ParticleSea

以下はで書かれた別のパーティクルシステムである粒子の海、一部を行うことができます興味を持っています:

おすすめ

転載: www.cnblogs.com/lijianming180/p/12433283.html