制作光环
本次作业基本要求是三选一
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); } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」