Unity3D 5 官方教程:粒子系統 How-Tos

這部分解釋瞭如何實現粒子系統的普遍類型。文檔中所有的代碼,你都可以免費使用於任何目的。

一個簡單的爆炸

你可以用一個粒子系統來創造出一個逼真的爆炸,但動態效果在一開始可能看起來會更混亂。精髓之處在於,一個爆炸只是粒子羣的向外爆發;但你可以做一些調整,讓它看起來更真實。
一個正在開發的爆炸

粒子的時間線

一個簡單的爆炸,產生一個向所有方向飛速擴散的球形火焰。初始的爆發擁有大量能量,因此非常熾熱(即,明亮),並極快地移動。能量會迅速消散,讓火焰的擴散減緩並冷卻(即,變得不如原來那樣明亮)。最後,隨着所有能量燃燒殆盡,火焰停止,很快完全消失。
一個爆炸粒子通常只有短暫的生命期,你可以改動一些生命期的設置來模擬這一效果。粒子在開始應非常快地離開爆炸中心,但隨着遠離,它的速度應大幅降低。同時,顏色應從一開始爲明亮的,之後變暗,最後褪色到透明。最後,在粒子的生命期內降低它的尺寸,會形成火焰隨着燃料耗盡而分散的效果。

實現

從默認的粒子系統對象開始(菜單:GameObect->Create General->Particle System),進入Shape模塊,設置發射器的形狀爲一個小的球體,比如半徑爲0.5個單位。標準資源庫中的粒子包含了一個名爲Fire Add 的材質,很適合用於爆炸(菜單:Assets->Import Package->Particles)。你可以將用於粒子系統的材質設置爲使用Renderer模塊。隨着Renderer開啓,你應同時關閉Cast Shadows(製造陰影)和Recieve Shadows(接受陰影),因爲爆炸火焰應該是發出光而非接收光。
這一步,這粒子系統看起來像有許多小的火球被從一箇中心點扔出來。爆炸當然應該同時產生大量粒子的爆發。在Emission模塊,你可以設置Rate值爲0,並在時間點0處添加單個粒子的Burst。爆發的粒子數量依賴於你所希望的爆炸強度,但50個粒子是個不錯的開始。隨着爆發設置完成,這個爆炸比之前像多了,但它相當地慢,並且火焰看起來耽擱很久。在Particle System模塊中(與遊戲對象會有相同的名字,例如“Explosion”),設置系統中粒子的Duration和Start Lifetime爲兩秒。
你也可以使用Size Voer Lifetime模塊來創造“火焰耗盡燃料”的效果。將尺寸曲線設置爲使用“ramp down”(即,尺寸從100%開始,降低至0)。爲了讓火焰黯淡、褪色,啓用 Color Over Lifetime模塊,並設置梯度從左邊的白色開始,到右邊的黑色結束。由於Fire Add材質使用附加的着色器來渲染,顏色屬性的黯淡也控制了粒子的透明度;火焰的透明度會變得完全透明,隨着顏色褪至黑。並且,當一個粒子被繪製在另一個之上時,附帶的材質允許粒子的亮度“相加”。這進一步加強了在爆炸起始所有粒子相互間都很接近時,那刺眼奪目的效果。
按照現在的情況,爆炸正在成型,但它看着像是在外太空發生的。粒子在褪色之前,以不變的速度向外逸散,移動相當長的距離。如果你的遊戲設定是在太空中,這大概是你想要的準確效果。然而,在大氣層內發生的爆炸會被周圍的空氣所減速並抑制。開啓Limit Velocity Over Lifetime模塊,設置Speed爲3.0,Dampen fraction 爲0.4;你應該會看到爆炸隨着進程而減少強度。
最後要注意的是,隨着粒子從爆炸中心離開,它們個體的形狀變得更容易辨認。特別地,相同尺寸、相同旋轉的粒子讓這個情況更明顯,相同的圖像被重複用於每個粒子。避免這一情況的一個簡單辦法,是在粒子生成時,對尺寸和旋轉進行隨機的變動。在Particle System模塊中檢視器的頂部,點擊Start Size和Start Rotation屬性的右向小箭頭,都設置爲Between Two Constants(在兩個常數間隨機)。對於尺寸,設置值在0.5到1.5,來產生一些變化,而沒有出現太多巨大或微小粒子的風險。現在應該會看到,粒子圖像的重複現象少多了。

用法

在測試時,將Looping屬性開啓,有助於重複地觀看爆炸;但在最終的遊戲裏,應該將它關掉,讓爆炸僅發生一次。當爆炸是爲有爆炸可能的對象(比如油箱)而設計時,可能希望將粒子系統組件添加到對象上,並讓Play On Awake屬性關閉。之後可以在腳本中於必要之時啓動爆炸。
void Explode() {
var exp = GetComponent();
exp.Play();
Destroy(gameObject, exp.duration);
}
在其它情況下,爆炸發生在撞擊產生的位置。如果爆炸來自於一個物體(例如,一顆手榴彈)那麼你可以在一個延時之後、或當它碰撞到目標後,調用上方所示的Explode函數。

// Grenade explodes after a time delay.
public float fuseTime;

void Start() {
    Invoke("Explode", fuseTime);
}

// Grenade explodes on impact.
void OnCollisionEnter(Collision coll) {
    Explode();
}

對於遊戲裏不被實際表現的物體(例如,一個運動速度太快而無法被看到的拋射體)所產生的爆炸,可以僅僅在合適的位置實例化一個爆炸。可以從例如光線照射的結果,來決定(爆炸)接觸點(從而在接觸點實例化爆炸)。

// On the explosion object.
    void Start() {
        var exp = GetComponent<ParticleSystem>();
        exp.Play();
        Destroy(gameObject, exp.duration);
    }

// Possible projectile script.
public GameObject explosionPrefab;

void Update() {
    RaycastHit hit;

    if (Physics.Raycast (Camera.main.ScreenPointToRay (Input.mousePosition), out hit)) {
        Instantiate (explosionPrefab, hit.point, Quaternion.identity);
    }
}

更深入的想法

這裏開發的爆炸很基礎,但可以修改它的很多部分,來達到在遊戲中所希望看到的實際效果。
你使用的粒子圖像將對玩家如何“閱讀”爆炸產生很大的影響。小型的粒子多,那麼分散可見的火星一邊燃燒一邊逸散。不會完全分散開的更大粒子更像是個被毀壞的油箱產生的火球。尤其是,將需要一併改變部分屬性來完成效果。例如,火球會堅挺更久,並且在它消失前會擴張得更少;而一個猛烈的爆炸會將燃燒的部分撒佈到相當遠的距離外。
這裏有一些屬性用隨機值設置,但其它大量屬性有“在兩個常數/曲線之間隨機”的選項,可以使用這些來增加各種各樣的變化。改變尺寸和旋轉來避免明顯的粒子雷同效果;考慮在Start Delay、Start Speed 屬性增加一些隨機。少量的變化有助於加強爆炸的效果顯得更“自然”及難以預料,而不是有控制的機械過程。更大量的變化導致一個“髒(dirty)”爆炸。例如,改變Start Delay將產生一個不猛烈但更慢的爆炸,可能是因爲車輛裏的油箱是被分別點燃的。

車的尾氣

轎車和許多其它類型的車輛在將燃料轉化爲動力時,會排除尾氣。可以用粒子系統來增加一個排氣爲車輛增加漂亮的最後一筆。
An exhaust generated by a particle system

粒子的時間線

尾氣從排氣管飛快地出現,但隨後接觸空氣後迅速減緩。隨着緩慢,尾氣擴散,變得模糊,很快消散在空氣中。由於尾氣是熱的,在它經過周圍的冷空氣時,也有輕微的上升。
尾氣粒子初始時,直徑不應大過排氣管;但在短暫的生命期裏可以在尺寸上有合理的增長。通常初始時有一些透明,隨着與空氣混合褪至完全透明。考慮到動態性,粒子會被非常快地發射,但之後迅速減緩,並且輕微地上升。

實現

在Shape模塊,選擇圓錐形狀並將Angle屬性設置爲0;這裏的“圓錐”將實際上作爲一個圓柱形的排氣管。排氣管的半徑理應取決於車輛的尺寸,但通常可以通過匹配場景視角中的車輛模型來設置(例如,一個轎車模型的背後通常會有一個你可以匹配尺寸的排氣管)。關於你選擇的屬性設置,半徑實際上決定了相當多,比如粒子的大小和發射速率。處於本例的目標,我們假設車輛是個小轎車,在Unity世界座標下的標準尺寸爲1米,排氣管的半徑則是0.05或者說是5釐米。
對煙霧粒子,一個適合的圖像是在標準資源庫中提供的Smoke4材質。如果尚未擁有,從菜單中的Assets->Import Package->Particles導入。然後,轉至粒子系統的Renderer模塊,設置材質屬性爲Smoke4。
默認的5秒生命期通常對於車輛尾氣來說太長了,所以應當打開粒子系統模塊(與遊戲對象有相同的名字,例如,“Exhaust”)並設置Start Lifetime爲2.5秒。同樣也在這個模塊裏,設置Simulation Space to World和Gravity Modifier 爲小的負值,比如-0.1。使用世界模擬空間能讓煙霧垂懸在它產生的地方,哪怕車輛在移動。負的重力影響引起煙霧粒子上升,彷彿他們是由熱氣組成的。一個很棒的額外效果是使用Start Rotation旁邊的菜單箭頭,選擇在兩個常數間隨機的選項。分別設置兩個值爲0和360,煙霧粒子在被髮射時會隨機地旋轉。許多一致對齊的粒子存在容易被察覺,減損本應是隨機、無定型的煙跡。
在這一步,煙霧粒子開始看起來真實可信,默認的發射速率創造了引擎間歇性燃燒的“噗噗”效果。然而,煙霧還沒有向外翻滾和消散。打開Color Over Lifetime模塊,點擊頂部在右邊的梯度停止(這控制了顏色的“alpha”值透明度)。設置alpha值爲0,可以看到煙霧粒子在場景中褪至無形。取決於引擎有多清潔,可能也希望降低開始時梯度的alpha值,黯淡的煙代表着髒、低效率的燃燒。
在褪至透明的同時,煙也應該隨着逸散而在尺寸上增加,可以在Size Over Lifetime模塊中很容易地創造出這個效果。打開這個模塊,選擇曲線,滑動曲線塊到左邊,使粒子以完整尺寸的部分值開始。你選擇的實際值取決於排氣管的尺寸,但比排氣管尺寸稍大一點點的值,會產生很棒的氣體逸散效果。(用排氣管的尺寸作爲粒子的起始,意味着氣體被排氣管限制而保持形狀,可是,氣體當然沒有既定的形狀 呀 !)使用粒子系統在場景視圖中的模擬來得到煙霧好的視覺效果。如果煙沒有散播到你希望的足夠遠那種效果,可以在在粒子系統模塊中增加Start Size。
最後,煙霧應當隨着它散播而減速。讓這發生的簡單辦法是Force Over Lifetime模塊。打開這個模塊,設置Space選項爲本地,力的Z方向分量設置爲一個負的值,標明粒子被這個力推向後方(系統沿着物體本地空間的Z軸正方向發射粒子)。大約爲-0.75的值會表現得很好,如果其他參數也如之前建議那樣的設置。

使用

可以將這個尾氣粒子系統放在車輛對象的一個子物體下。對於簡單的遊戲,可以開啓 Play On Awake和Looping屬性,讓系統運行起來。然而在大多數情況下,隨着車輛移動,可能希望至少改變發射率。這首先是爲了可靠性(即,引擎工作更賣力時,產生更多的煙),不過這也有助於阻止煙霧粒子隨着車輛移動而分散。一輛飛速移動的車,而發射率太慢,將會產生明顯的煙霧“噴出”效果,這相當不真實。
可以從腳本中輕鬆地改變發射率。如果在腳本中有個代表引擎轉數或者車速的變量,可以簡單地用一個常數乘以這個值,將結果賦予粒子系統的EmissionRate屬性。
// C#

using UnityEngine;
using System.Collections;

public class PartScriptTestCS : MonoBehaviour {

    public float engineRevs;
    public float exhaustRate;

    ParticleSystem exhaust;


    void Start () {
        exhaust = GetComponent<ParticleSystem>();
    }


    void Update () {
        exhaust.emissionRate = engineRevs * exhaustRate;
    }

}



// JS

var engineRevs: float;
var exhaustRate: float;

var exhaust: ParticleSystem;


function Start() {
    exhaust = GetComponent.<ParticleSystem>();
}


function Update () {
    exhaust.emissionRate = engineRevs * exhaustRate;
}

更深入的想法

基本方案已然創建了一個逼真的車輛尾氣。但你可能注意到了,你修改參數時,引擎的“特點”改變了。一個缺少調教、燃燒率低的引擎會不完全地燃燒燃料,導致濃密、黑漆漆的煙霧,在空氣中揮之不去。這完美地契合了老舊農場拖拉機,但絕不適合高性能運動跑車。對於一個“清潔”的引擎,應當對生命期、不透明性和尺寸的上升,使用小的數值。對於一個“髒”的引擎,應當增加這些值,試試使用Emission模塊的Bursts屬性來產生引擎噼裏啪啦的效果。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章