ユニティパーティクルシステム - 粒子オーラ
序文
これは2019年の3Dゲームプログラミングとデザインの科学の中山大学及びコンピュータデータ第八の仕事である
すべてのプロジェクトとgithubのにアップロードされたコードを、訪問する歓迎します。
githubのプロフィール:https://starashzero.github.io
3Dゲームプログラミングとホームページのデザイン:https://starashzero.github.io/3DGameDesign
この割り当てプロジェクト住所:https://github.com/StarashZero/3DGameDesign/tree /マスター/ hw8
プロジェクトの要件
参考パンの先生がブログ
この作品は、3つの基本的な要件の一つであります
- 1、粒子の単純な生産
基準リソース要件に応じては、パーティクルシステムを作成し、参照リソースの
使用は、制御コードが異なるシナリオの下で使用しても同様の効果はないように、第3.3節に記載さ - 2は、公式の「車の排気ガス」シミュレート完成
車の車両用公式資源の資源、打ち上げ、実行、不具合などに開始した粒子系シミュレーションシーンエフェクト煙の使用を - 図3は、このような「粒子ハロ」とは、粒子フロープログラミングを使用して、いくつかの制御効果を作るために、http://i-remember.fr/enような部位を参照する
以前の研究を参照することができます
私はシンプルな著作権侵害http://i-remember.fr/enページの効果を完了するために、第三を行うことにしました
エフェクト作品
- オーラの生成プロセス
- ハロー収縮と削減
- ビデオプレゼンテーション
https://v.youku.com/v_show/id_XNDQyNTE2MzM5Mg==.html?spm=a2h3j.8428770.3416059.1
プリセット体
オーシャン粒子、粒子オーラ:2つのプリセット本体があります。
次のように空のオブジェクトを作成し、パーティクルシステムコンポーネントを追加するために開始され、設定された属性:
コードの説明
- ParticleSea
記事への粒子の海コード書かれた参照ユニティ粒子が!素晴らしい海を生産
のみパラメータの一部を変更するために、行われていませんどのくらいの変化public class ParticleSea : MonoBehaviour { ParticleSystem particleSystem; ParticleSystem.Particle[] particlesArray; public float spacing = 1; public int seaResolution = 100; public float noiseScale = 0.1f; public float heightScale = 4f; float perlinNoiseAnimX = 0.01f; float perlinNoiseAnimY = 0.01f; public Gradient colorGradient; void Start() { particleSystem = gameObject.GetComponent<ParticleSystem>(); particlesArray = new ParticleSystem.Particle[seaResolution * seaResolution]; particleSystem.maxParticles = seaResolution * seaResolution; particleSystem.Emit(seaResolution * seaResolution); particleSystem.GetParticles(particlesArray); } private void Update() { for (int i = 0; i < seaResolution; i++) { for (int j = 0; j < seaResolution; j++) { float zPos = Mathf.PerlinNoise(i * noiseScale + perlinNoiseAnimX, j * noiseScale + perlinNoiseAnimY); particlesArray[i * seaResolution + j].startColor = colorGradient.Evaluate(zPos); particlesArray[i * seaResolution + j].position = new Vector3(i * spacing, zPos * heightScale, j * spacing); } } perlinNoiseAnimX += 0.01f; perlinNoiseAnimY += 0.01f; particleSystem.SetParticles(particlesArray, particlesArray.Length); } }
- ParticleRing
粒子数基準コードハロ兄弟ブログ、およびそれらの理解によれば、多くの機能を追加し
、粒子半径の記録に加えて、粒子の記録位置の構造を使用する必要があり、外側の走行時の角度追記をします今制御された半径(第一の粒子径)、粒子の位置の還元を促進
内CirclePosition[] circles; //粒子位置 class CirclePosition { public float radius = 0f, angle = 0f, time = 0f, targetRadius = 0f; public CirclePosition(float radius, float angle, float time, float targetRadius) { this.radius = radius; //半径 this.angle = angle; //角度 this.time = time; //运行时间 this.targetRadius = targetRadius; //约束半径 } }
Start()
のパラメータの関数で初期化され、インデックスによってソート粒子の位置を確保するために、さらに必要に応じて、粒子の特性を設定するために、達成するために、粒子の漸進的な出現の開始を容易にする効果
粒子の漸進的な出現の効果を達成するために、粒子は、ハローの発生時間を記録する必要がある、とインデックスに基づいて粒子の漸進的な出現を許可しますpublic int count = 3000; //粒子数量 public float size = 0.1f; //粒子大小 public float maxRadius = 12f; //最大半径 public float minRadius = 7f; //最小半径 public float speed = 2f; //初始速度 void Start() { particlesArray = new ParticleSystem.Particle[count]; circles = new CirclePosition[count]; particleSystem = gameObject.GetComponent<ParticleSystem>(); particleSystem.maxParticles = count; particleSystem.startSize = size; particleSystem.Emit(count); particleSystem.GetParticles(particlesArray); float midRadius = (maxRadius + minRadius) / 2; float minRate = Random.Range(1.0f, midRadius / minRadius); float maxRate = Random.Range(midRadius / maxRadius, 1.0f); for (int i = 0; i < count; i++) { //设置半径 float radius = Random.Range(minRadius * minRate, maxRadius * maxRate); //设置角度 float angle = (float)i / count * 360f; float theta = angle / 180 * Mathf.PI; //保存粒子初位置 circles[i] = new CirclePosition(radius, angle, (float)i / count * 360f, radius); //设置粒子初位置 particlesArray[i].position = new Vector3(radius * Mathf.Cos(theta), radius * Mathf.Sin(theta), 0); } particleSystem.SetParticles(particlesArray, particlesArray.Length); }
半径の変動を許容しつつ、粒子運動を行うことができます、あなたは、粒子の角度を変更するには、粒子を必要とする動きがより自然なので、public float time = 0; //时间 //增加时间,并计算当前应该显示的粒子的最低索引 time = (time + Time.deltaTime) > 5 ? 5 : (time + Time.deltaTime); int tar = count - (int)(Mathf.Pow(time / 5, 3) * count); //设置粒子颜色 if (i < tar) particlesArray[i].startColor = gradient.Evaluate(0.5f); //粒子全透明 else { float deep = circles[i].angle / 360f > 0.6f ? (circles[i].angle / 360f) : (circles[i].angle / 360f < 0.4f ? circles[i].angle / 360f : 0.4f); //不允许全透明 particlesArray[i].startColor = gradient.Evaluate(deep); }
オーラを縮小することができましょう、最も簡単な方法は、粒子が運動の最大半径とともに変化することができなければならないように、最大半径を減少させることです//粒子角度增加 circles[i].angle = (circles[i].angle - Random.Range(0.4f, 0.6f) + 360f) % 360f; float theta = circles[i].angle / 180 * Mathf.PI; //粒子半径变动 circles[i].time += Time.deltaTime; circles[i].radius += Mathf.PingPong(circles[i].time / minRadius / maxRadius, pingPong) - pingPong / 2.0f;
最大半径が増加すると、粒子の位置が自動的に元の位置に復元する場合、粒子の変位が制御された半径を必要とする傾向があります//将粒子锁定至最大半径与最小半径之间 if (circles[i].radius < minRadius) circles[i].radius += Time.deltaTime; else if (circles[i].radius>maxRadius) circles[i].radius -= Time.deltaTime;
//约束粒子半径,使得粒子有向初半径位移的趋势 if (circles[i].radius < circles[i].targetRadius) circles[i].radius += 0.01f; else if (circles[i].radius > circles[i].targetRadius) circles[i].radius -= 0.01f;
- SimpleController
SimpleControllerは、シンプルなコントローラであり、粒子と粒子のオーラの海、そしてハンドルユーザーのクリックイベントを発生させますpublic class SimpleController : MonoBehaviour { GameObject particleSea; GameObject particleRing; // Start is called before the first frame update void Start() { //生成粒子光环 particleRing = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>("Prefabs/ParticleRing"), new Vector3(0, 0, 15), Quaternion.identity); } // Update is called once per frame void Update() { //当粒子光环完全出现后生成粒子海洋 if (particleSea == null && particleRing.GetComponent<ParticleRing>().time == 5) particleSea = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>("Prefabs/ParticleSea"), new Vector3(-45, -8, -5), Quaternion.identity); } private void OnGUI() { //当用户点击按钮后,改变粒子光环的最大半径 if (particleSea != null&&GUI.Button(new Rect(Screen.width/2-20,Screen.height/2-10,40,40), "+")) { particleRing.GetComponent<ParticleRing>().maxRadius = particleRing.GetComponent<ParticleRing>().maxRadius == 12 ? 9 : 12; } } }