制作光环

本次作业基本要求是三选一

1、简单粒子制作

  • 按参考资源要求,制作一个粒子系统,参考资源
  • 使用 3.3 节介绍,用代码控制使之在不同场景下效果不一样

2、完善官方的“汽车尾气”模拟

  • 使用官方资源资源 Vehicle 的 car, 使用 Smoke 粒子系统模拟启动发动、运行、故障等场景效果

3、参考 http://i-remember.fr/en 这类网站,使用粒子流编程控制制作一些效果, 如“粒子光环”

  • 可参考以前作业

参考了师兄的博客https://blog.csdn.net/simba_scorpio/article/details/51251126,这些代码就不再赘述了。师兄已经讲的很清楚了。

表示感谢

 

 

同时加入了自己的一些想法,扩展了几个功能,同时加入了奥运五环的元素。

 

不过由于有了师兄的代码,我的部分实现起来就比较简单了。

view.cs 控制界面,以及环的几个运动

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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class View : MonoBehaviour
{
    public GameObject go1;
    public GameObject go2;
    public GameObject go3;
    public GameObject go4;
    public GameObject go5;
 
    private Vector3 vgo1;
    private Vector3 vgo2;
    private Vector3 vgo3;
    private Vector3 vgo4;
    private Vector3 vgo5;
 
    private bool gather;
    private bool rotating;
    private bool scaling;
    // Start is called before the first frame update
    void Start()
    {
        gather = false;
        vgo1 = go1.transform.position;
        vgo2 = go2.transform.position;
        vgo3 = go3.transform.position;
        vgo4 = go4.transform.position;
        vgo5 = go5.transform.position;
    }
 
    // Update is called once per frame
    void Update()
    {   if (gather)
        {
            go1.transform.position = Vector3.MoveTowards(go1.transform.localPosition, new Vector3(0f, 0f, 0f), Time.deltaTime * 1);
            go2.transform.position = Vector3.MoveTowards(go2.transform.localPosition, new Vector3(0f, 0f, 0f), Time.deltaTime * 1);
            go3.transform.position = Vector3.MoveTowards(go3.transform.localPosition, new Vector3(0f, 0f, 0f), Time.deltaTime * 1);
            go4.transform.position = Vector3.MoveTowards(go4.transform.localPosition, new Vector3(0f, 0f, 0f), Time.deltaTime * 1);
            go5.transform.position = Vector3.MoveTowards(go5.transform.localPosition, new Vector3(0f, 0f, 0f), Time.deltaTime * 1);
        }
        else
        {
            go1.transform.position = Vector3.MoveTowards(go1.transform.localPosition, vgo1, Time.deltaTime * 1);
            go2.transform.position = Vector3.MoveTowards(go2.transform.localPosition, vgo2, Time.deltaTime * 1);
            go3.transform.position = Vector3.MoveTowards(go3.transform.localPosition, vgo3, Time.deltaTime * 1);
            go4.transform.position = Vector3.MoveTowards(go4.transform.localPosition, vgo4, Time.deltaTime * 1);
            go5.transform.position = Vector3.MoveTowards(go5.transform.localPosition, vgo5, Time.deltaTime * 1);
        }
    }
 
    void OnGUI()
    {
        //大字体初始化
        GUIStyle bigStyle = new GUIStyle();
        bigStyle.normal.textColor = Color.white;
        bigStyle.fontSize = 30;
 
        if (GUI.Button(new Rect(0, 0, 100, 100), "旋转", bigStyle))
        {
            UnityEngine.Debug.Log("点击旋转");
            go1.GetComponent<Rotate>().rotating = !go1.GetComponent<Rotate>().rotating;
            go2.GetComponent<Rotate>().rotating = !go2.GetComponent<Rotate>().rotating;
            go3.GetComponent<Rotate>().rotating = !go3.GetComponent<Rotate>().rotating;
            go4.GetComponent<Rotate>().rotating = !go4.GetComponent<Rotate>().rotating;
            go5.GetComponent<Rotate>().rotating = !go5.GetComponent<Rotate>().rotating;
        }
 
        if (GUI.Button(new Rect(200, 0, 100, 100), "伸缩", bigStyle))
        {
            UnityEngine.Debug.Log("点击伸缩");
            go1.GetComponent<ParticleHalo>().scaling = !go1.GetComponent<ParticleHalo>().scaling;
            go2.GetComponent<ParticleHalo>().scaling = !go2.GetComponent<ParticleHalo>().scaling;
            go3.GetComponent<ParticleHalo>().scaling = !go3.GetComponent<ParticleHalo>().scaling;
            go4.GetComponent<ParticleHalo>().scaling = !go4.GetComponent<ParticleHalo>().scaling;
            go5.GetComponent<ParticleHalo>().scaling = !go5.GetComponent<ParticleHalo>().scaling;
        }
        if (GUI.Button(new Rect(400, 0, 200, 100), "聚散", bigStyle)) {
            UnityEngine.Debug.Log("聚散");
            gather = !gather;
        }
    }
 
}

 

控制光环旋转

Rotate.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class Rotate : MonoBehaviour
{
    public Transform tf;
    public int speed;
    public bool rotating = false;
    // Start is called before the first frame update
    void Start()
    {
        speed = 100;
    }
 
    // Update is called once per frame
    void Update()
    {
       if (rotating) tf.Rotate(Vector3.forward * speed * Time.deltaTime);
    }
}

 

控制光环的生成,同时控制光环的伸缩

ParticleHaro.cs

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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
 
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;       // 时间
    }
}
 
    public class ParticleHalo : MonoBehaviour
{
    public ParticleSystem particleSys;  // 粒子系统
    private ParticleSystem.Particle[] particleArr;  // 粒子数组
    private CirclePosition[] circle; // 极坐标数组
 
    public int count = 10000;       // 粒子数量
    public float size = 0.1f;      // 粒子大小
    public float minRadius = 5.0f;  // 最小半径
    public float maxRadius = 9.0f; // 最大半径
    public bool clockwise = true;   // 顺时针|逆时针
    public float speed = 2f;        // 速度
    public float pingPong = 0.01f;  // 游离范围
    // Start is called before the first frame update
    public Gradient colorGradient;
    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);
 
        // 初始化梯度颜色控制器
        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);
 
            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);
    }
 
    private int tier = 10;  // 速度差分层数
 
    private float time = 0;
    private bool jian = false;
    public bool scaling = false;
    void Update()
    {
 
        if (((int)time % 18) == 0 && scaling)
        {
            jian = false;
            UnityEngine.Debug.Log("改变2");
        } else if (((int)time % 9) == 0 && scaling)
        {
            jian = true;
            UnityEngine.Debug.Log("改变1");
        }
        //增大和缩小半径范围
        if (jian && scaling)
        {
            minRadius = minRadius - 0.01f;
            maxRadius = maxRadius - 0.01f;
             
        } else if (scaling)
        {
            minRadius = minRadius + 0.01f;
            maxRadius = maxRadius + 0.01f;
        }
        if (scaling) time = time + Time.deltaTime;
 
 
        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);
        }
 
        RandomlySpread();   // 初始化各粒子位置
        particleSys.SetParticles(particleArr, particleArr.Length);
    }
}

  

posted @   woodx  阅读(218)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示