3D游戲第八次作業-煙花粒子效果實作
結果展示
先來個結果鎮樓
下面是一個影片演示:
最終效果演示
本次專案使用的資源:
Unity Particle Pack:使用的Flame 01以及Twinkle等material均來自這個包,且該包有較多的示例,
粒子效果制作
我們的煙花分為以下5個部分組成:
其中,Firework主體也是一個粒子系統,它擁有下轄的5個粒子系統作為子部件,我們利用粒子系統面板中的__Sub Emitters__使得Firework所發射的每個粒子都擁有子部件的粒子效果,實際上,Firework主體只是提供一個粒子的移動,具體的粒子渲染效果全部由Firework的五個子部件來完成;
我們將從各個子部件的實作開始,逐步講解,最后在Firework中完成各個粒子效果的合并;
trail子部件
即我們的煙花在爆炸之前飛行程序中產生的尾跡:
我們可以看到,我們的尾跡中的粒子在運動程序中發生了一些變化,總結如下:
- size:粒子的大小先變大再變小;
- color:粒子的顏色隨著運動時間的變化而變化,
- velocity:粒子在產生后向四周擴散,使尾跡變大,如同煙霧;
那么我們如何創建這樣一個trail粒子效果呢?
-
創建tail: 右鍵 → Effects → Particle System 創建一個新的粒子系統,然后我們給它取名為 trail,
-
__設定粒子大小動態變化:__打開trail的粒子系統面板,勾選__size over lifetime__選項,并在面板下方設定粒子在運動中的size變化的曲線如下,
通過我們的size變化的曲線,我們可以知道我們的trail所發射的粒子的大小變化為:
__緩慢變大 → 保持一段時間大小 → 緩慢變小 → 瞬間變大→ 瞬間變小 __
最后一段的瞬間變大再瞬間變小是為了模擬粒子灰燼的閃動效果,
-
設定粒子顏色動態變化: 打開trail的粒子系統面板,勾選__color over lifetime__選項,并設定顏色如下:
最后一段顏色接近于橙紅色,和粒子動態變化最后一部分的瞬間變化相結合,可以模擬出粒子灰燼的閃動效果,
-
設定粒子運動: 打開trail的粒子系統面板,勾選__Velocity over lifetime__選項,選擇粒子運動的速度變化方式為__Random between two curves__,
然后令x軸和z軸方向上的速度變化曲線如下:
而y軸方向上的速度變化不要改變,一直保持為0即可,
這樣,尾跡粒子在被產生之后就會向四周隨機擴散,使得尾跡整體變大,模擬煙霧的擴散效果;
-
__設定粒子的發射方向:打開trail的粒子系統面板,勾選__Shape__選項,并選擇shape為__sphere,這樣粒子在產生的時候就會在煙花的周圍隨機產生,而不是直接從煙花尾部直直地產生,更加貼合現實,
-
設定Emission和粒子系統主模板
twinkle子部件
twinkle子部件用于在煙花爆炸的時候產生一個閃光,模擬煙花爆炸時的閃光,
我們從這段影片中看到,粒子從小變大,然后瞬間變小,并在這個程序中微微旋轉,因此,我們根據這個效果來設計我們的粒子系統;
步驟:
-
創建twinkle: 右鍵 → Effects → Particle System 創建一個新的粒子系統,然后我們給它取名為 twinkle,
-
設定粒子的渲染圖片為twinkle: 打開twinkle的粒子系統面板,打開__Render__選項,并改變material為Twinkle.
-
__設定粒子大小動態變化:__打開twinkle的粒子系統面板,勾選__size over lifetime__選項,并在面板下方設定粒子在運動中的size變化的曲線如下:
-
設定粒子動態旋轉: 打開twinkle的粒子系統面板,勾選__Rotation over lifetime__選項即可,不需要特意改動什么值;
-
設定Emission和粒子系統主模板
在這里,我們將Emission的Rate Over time,即每秒發射多少個粒子置為0,因為我們的閃光只在煙花爆炸的時候才出現,在煙花飛行的程序中不應該發射出閃光,我們轉而設定Emission的Bursts,設定Bursts中的Count為1,使得Twinkle在發射粒子的時候只發射一個;Time表示發生爆炸的時候Twinkle發生一次Bursts的延遲時間,
Explore子部件
即煙花爆炸的時候產生的球型光雨:
在圖中,我們可以看到球型光雨的運動特性:
- size:類似trail的粒子,緩慢變大,再緩慢變小,之后迅速變大再迅速變小來模擬灰燼的閃爍效果;
- color:同樣類似trail的粒子,在運動程序中不斷變化;
- 發射方向:所有的粒子呈球型向四周擴散;
根據以上效果,我們就可以開始我們的設計;
步驟:
-
創建explore: 右鍵 → Effects → Particle System 創建一個新的粒子系統,然后我們給它取名為 Explore,
-
__設定粒子大小動態變化:__打開explore的粒子系統面板,勾選__size over lifetime__選項,并在面板下方設定粒子在運動中的size變化的曲線如下:
基本上和trail的粒子的size變化一樣;
-
設定粒子顏色動態變化: 打開explore的粒子系統面板,勾選__color over lifetime__選項,并設定顏色如下:
和trail的步驟其實一模一樣,只是顏色有所不同,你可以根據自己的喜好來創建喜歡的運動漸變顏色,
-
設定粒子的發射方向:打開explore的粒子系統面板,勾選__Shape__選項,并選擇shape為__sphere,這樣粒子就會呈球型產生,并向上下左右擴散,至于trail中為什么粒子沒有呈球型擴散呢,是因為我們額外為trail中的粒子勾選了__Velocity over lifetime,并使粒子在原來的運動的基礎上再向四周擴散,從而沒有產生球型,
-
設定Emission和粒子系統主模板
同樣,我們對于球型光雨的要求也是在爆炸的時候才產生,因此Emission的Rate Over time同樣置為0,而使用Bursts,和twinkle不同,光雨一次要產生很多,一次,count的數量是1000,即每個爆炸都發射1000個粒子,
Fire samll子部件
即我們飛行中的煙花:
從煙花的飛行程序中我們可以看出:
- 煙花的尾部出現抖動;
- 煙花本身是一個影片,即火焰存在出現到消失的程序;
根據這些,我們開始我們的制作:
-
創建small fire: 右鍵 → Effects → Particle System 創建一個新的粒子系統,然后我們給它取名為 Fire small,
-
設定粒子的渲染圖片為Flame 01: 打開Fire small的粒子系統面板,打開__Render__選項,并改變material為Flame 01.
- Flame 01為一組火焰的圖片;
-
__設定影片:__打開Fire small的粒子系統面板,打開__Texture sheet animation__選項,設定如下:
其中Mode默認為Grid模式,不必改動,在Mode下的Tiles中的
x=7, y=7表示我們將Flame 01這張影像切分為7*7的網格,網格中的每一格代表影片的一幀,我們的影片將從第一幀開始播放到最后一幀,即第49幀,其他的屬性保持默認即可;這樣,我們產生的粒子就會是一個自動變化的粒子, -
__設定粒子的發射方向:打開Fire small的粒子系統面板,勾選__Shape__選項,并選擇shape為__cone,即從錐體的底部或頂部發射粒子,設定具體如下:
其中:
- Angle:錐體的上底面,即發射粒子的面,相對于下底面的張開幅度,0表示和下底面的張開幅度相同,因此,在Fire small里的錐體呈圓柱形;
- Radius:錐體的下底面的半徑;
其他均為默認值即可;但是由于錐體的上底面原本的方向不是直接指向下方的,所以我們要對粒子系統進行旋轉,Fire small的transform如下:
-
__設定粒子的抖動:__可以看到我們的煙火在運動程序中是不斷抖動的,這是為了模擬煙花在飛翔程序中受到氣流影響造成的火焰的抖動效果,我們直接勾選__Noise__選項即可,
-
設定粒子顏色動態變化: 打開Fire small的粒子系統面板,勾選__color over lifetime__選項,并設定顏色如下:
因為我們原來的圖片在播放影片的時候尾焰比較大,我們讓影片的透明度在后面均為1,使得尾焰變小,
-
設定Emission和粒子系統主模板
在Fire small中的Emission,我們沒有使用Rate over time和Bursts,而是使用了Rate over Distance,Rate over Distance表示每個移動距離單位發射的粒子數,也就是說,我們的Fire small在運動中才會產生粒子,
Explore2子部件
即四散的光雨效果:
可以看到,我們的Explore2實際上只是一些粒子在呈球型發散,然后每個粒子都帶有我們的制作過的trail尾跡,它的實作也比較簡單,trail部分和我們前面所做的trail基本相同,只是在如粒子大小以及發射粒子的數目等引數方面存在差異,之后會指出,主要的部分還是Explore2這個部件的制作;
同樣的開始
-
創建Explore2: 右鍵 → Effects → Particle System 創建一個新的粒子系統,然后我們給它取名為 Explore2,
-
設定粒子的渲染圖片為Twinkle: 打開Explore2的粒子系統面板,打開__Render__選項,并改變material為Twinkle,這里復用一下Twinkle材料;
-
__設定粒子的發射方向:打開Explore2的粒子系統面板,勾選__Shape__選項,并選擇shape為__sphere,即以球型發射粒子,其他不用改動;
-
設定粒子動態旋轉: 打開Explore2的粒子系統面板,勾選__Rotation over lifetime__選項即可,不需要特意改動什么值;
-
設定粒子運動: 打開Explore2的粒子系統面板,勾選__Velocity over lifetime__選項,設定如下:
我們基本不改動選項中的內容,只是改動speed Modifier一項,這一項決定了粒子的運動速度,由于粒子在爆炸的時候是以很快的速度爆發,之后快速降速,再緩慢降速,因此,我們需要在speed Modifier中體現出這種速度變化;
-
設定粒子在運動中受重力: 打開Explore2的粒子系統面板,勾選__Force over lifetime__選項,并將z軸的力設為-20,使得粒子受到重力,在爆發后向地面墜落,模擬自然的重力;
-
__設定trail:__為了讓每個粒子都擁有自己的尾跡,我們打開Explore2的粒子系統面板,勾選__Sub Emitters__選項,將一個制作完成的trail子部件加入到Explore2中,成為Explore2的子部件,然后將trail設定為Explore2子粒子系統,設定如下:
設定trail在Explore2
Birth即開始運行的時候同時運行,這樣,trail的粒子效果就能加入到每個Explore2的粒子中,產生尾跡; -
設定Emission和粒子系統主模板
-
trail的改動:
- 主界面中的start size從1變為0.5;
- 主界面中的max Particles變為20000;
- Emission中的Rate over time變為100;
Firework主體
Firework主體的功能只是為煙花提供運動,因此不會產生任何粒子,各種粒子效果將由上面制作的各個部件來完成;
步驟:
-
創建Firework: 右鍵 → Effects → Particle System 創建一個新的粒子系統,然后我們給它取名為 Firework,
-
將以上創建成功的組件按照開篇的組成加入到Firework中,
-
__設定粒子的發射方向:打開Firework的粒子系統面板,勾選__Shape__選項,并選擇shape為__box,即以正方形發射粒子,由于box的默認發射方向在z軸正方向,因此,我們將Firework進行旋轉;
-
__設定粒子不渲染:由于Firework的粒子并不需要渲染,所以,我們在__Render__選項中設定渲染模式為__None;
-
__設定子粒子系統:__和Explore2類似,我們要勾選__Sub Emitters__選項,然后將Firework的所有子粒子系統加入到里面,設定如下:
其中和已經介紹的
Birth不同,Death是在粒子結束的時候才會觸發的事件,即當粒子結束的時候,我們的Twinkle,Explore和Explore2的粒子效果會同時發生,表現為煙花爆炸; -
設定Emission和粒子系統主模板
-
最終的效果:
制作放煙花場景:
代碼:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FireFirework : MonoBehaviour
{
// Start is called before the first frame update
public ParticleSystem[] firework;
public ParticleSystem.Particle[] m_Particles;
void Start()
{
GameObject[] temp;
// 獲取場景中所有的Firework,即煙花發射器;
temp = GameObject.FindGameObjectsWithTag("firework");
firework = new ParticleSystem[temp.Length];
Debug.Log(temp.Length);
// 將煙花發射器賦予firework陣列;
for(int i = 0; i < temp.Length; ++i)
{
firework[i] = temp[i].GetComponent<ParticleSystem>();
firework[i].Stop();
}
if (m_Particles == null)
{
m_Particles = new ParticleSystem.Particle[firework[0].main.maxParticles];
}
}
// Update is called once per frame
[System.Obsolete]
void Update()
{
if (Input.GetButtonDown("Fire1"))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//從攝像機發出到點擊坐標的射線
RaycastHit hit;
if (Physics.Raycast(ray, out hit)) {
// 在隨機選擇場景中的一個Firework;
int id = Random.Range(0, firework.Length);
// 利用該Firework發射一個粒子,即煙花;
firework[id].Emit(1);
// 獲取場景中屬于firework[id]的運行中的粒子;
int count = firework[id].GetParticles(m_Particles);
// 根據滑鼠點擊位置計算煙花的飛行時間;
float life_time = (hit.point.y - gameObject.transform.position.y) / firework[id].startSpeed;
// 根據滑鼠點擊位置和煙花飛行時間計算煙花的水平速度;
float x_v = (hit.point.x - gameObject.transform.position.x)/life_time;
// 設定剛剛發射的粒子的飛行時間;
m_Particles[count - 1].lifetime = life_time;
// 設定剛剛發射的粒子的速度;
m_Particles[count - 1].velocity = new Vector3(x_v, m_Particles[count - 1].velocity.y, m_Particles[count - 1].velocity.z);
// 將改動應用到場景中;
firework[id].SetParticles(m_Particles,count);
}
}
}
}
我在場景中放置了四個Firework,每個Firework擁有不同的煙花顏色,每次發射煙花將從四個煙花發射器中選一個進行發射,并設定煙花的飛行時間以及飛行速度,保證煙花到達滑鼠點擊的位置就爆炸,
以下是最終的效果展示:
最終效果演示
專案地址
專案連接-傳送門
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/229952.html
標籤:其他
上一篇:游戲行業發展趨勢,游戲行業怎么樣?游戲產業收入報告,游戲生態。
下一篇:初識Java語言
