Unity學習——粒子系統(Particle System)


內置粒子系統(Bulit-in Particle System)

Unity內置粒子系統允許你在Unity支持的平台中產生特效。

  • 可以使用 C#腳本來與系統和腳本中的粒子個體交互。
  • 粒子系統能使用Unity的底層物理系統,故可以和場景中的 Colliders交互。

使用內置粒子系統

內置粒子系統使用組件,所以在場景中放置一個粒子系統就是添加一個預先制作好的 GameObject(GameObject->Effects->Particle System)或添加這個組件到已存在的 GameObject中(Component->Effects->Particle System)。因為組件十分復雜,所以Inspector被分為許多可折疊的子部分或組件,分別包含一組相關屬性。此外,你可以通過Inspector中的Open Window按鈕,使用單獨的Editor窗口,同時編輯一個或多個系統。

當一個有 Particle System的 GameObject被選中時,Scene視圖就會包含一個小 Particle Effect面板,面板中有一些簡單的控制,用於可視化你對的系統設置做出的改變。

Playback Speed允許你加速或減慢粒子模擬,因此你可以馬上看到后續狀態。Playback Time表示系統開始運行的時間,它取決於 Playback Speed。Particle Count表示系統目前有多少粒子。

隨時間變化的屬性

許多粒子乃至整個粒子系統的數值屬性都能隨着時間而變化。Unity提供幾種不同的方法來指定變化的發生:

  • Constant:屬性值在它的生命周期中保持固定。
  • Curve:值由曲線/圖指定。
  • Random Between Tow Constant:兩個固定值,定義了值的上下界。實際值在范圍內隨着時間隨機變化。
  • Random Between Two Curves:兩條曲線,定義了在值的生命周期中的一個給定點的上下邊界。當前值在范圍內隨機變化。
    當你設置屬性為 Curve或 Random Between Two Curves,Particle Curves Curves編輯器會出現在Inspector的底部。

    要編輯曲線,點擊並拖動端點來改變曲線。

    Particle System Curves編輯器有兩個按鈕:
  • Optimize:將曲線擬合成四個或更少的keys來構建一個被稱為多項式的快速求值器,這比讀取未經優化的曲線更有效。
  • Remove:刪除選中的曲線。
    點擊選中key旁邊的齒輪,並選擇其中一個選項,可以編輯粒子系統 play曲線的方式。
  • Loop:在粒子生命周期中 play曲線特定次數。比如說,如果你畫一條曲線,讓粒子大小上下變化,你可以讓它循環幾次,在粒子死亡前讓“上下”動畫發生多次而不是一次。
  • Ping Pong:與Loop類似,但是是在持續震盪中使曲線前后變化。
  • Clamp: 將落在粒子時間范圍的粒子查詢限制為曲線的第一個或最后一個值。

Start Color屬性有以下幾個選項:

  • Color:所有粒子初始顏色都為設置的顏色。粒子在它們的生命周期中可以更改顏色。
  • Gradient:粒子系統發射粒子,粒子在梯度開始和梯度結束時顏色都為設置的顏色。梯度線代表粒子系統的生命周期;粒子系統從與粒子系統時間相對應的梯度點選擇顏色。
  • Random Between Tow Colors:粒子系統在兩個給定的顏色的一個隨機線性插值中選擇起始粒子顏色。
  • Random Between Tow Gradients:粒子系統從每個給定的梯度點中選擇一個顏色,該梯度點對應於系統當前的階段。起始粒子顏色是在這兩個被選中的顏色中使用隨機線性插值選取的。
  • Random Color:與 Gradient模式類似,粒子從定義好的梯度中選擇初始顏色。但是粒子系統不是基於粒子系統當前處於的階段選擇的,而是完全隨機。當 enabled后,你可以選擇一系列顏色,並為每個顏色附上選取概率。

為了計算最終的粒子顏色結果,粒子系統在每個通道中將不同模塊的顏色屬性相乘。
當你把粒子設置為 Gradient顏色是,Gradient編輯器會出現:

  • Mode:決定粒子顏色設置是否被混合。
  • Color:展示當前在 Gradient中被選中的key的顏色。使用它能編輯那個梯度位置的顏色。
  • Location:顯示被選中的key在 Gradient中的位置。
  • Presets:允許你保存 Gradient設置。點擊 New來使當前這一系列值 為Gradient預設值。
    每個通道中不同組件的顏色屬性相乘,以計算最終粒子顏色結果。

動畫綁定

所有粒子屬性都可以被 Animation系統所用。
要訪問粒子系統屬性,必須要有一個 Animator組件(Project視圖: create->Animator Controller)與粒子系統的 Gameobject相關聯。還需要添加 Animation Controller和 Animation(Project視圖: create->Animation)。

為了動畫化一個粒子系統屬性,打開包含選定 Animator和Particle System的 GameObject的 Animation窗口,點擊 Add Property來添加屬性。

點擊右邊的➕就可以添加了

創建簡單的爆炸

你可以使用粒子系統來構建爆炸效果。其核心在於,一個爆炸就是例子向外爆發,但是你可以對它做一些修改,以使其看起來更加真實。

粒子時間線

一個簡單的爆炸會產生向各個方向迅速擴展的火球。初始的爆炸有巨大能量,很熱(ie, 亮)且移動的很快。能量回迅速消散,導致火焰擴展逐漸變慢,並慢慢冷卻下來 (ie,亮度降低)。最終,當燃料燒光后,火焰也會完全消失。
爆炸粒子是最為典型地擁有短暫生命周期的粒子,你可以在它的生命周期中改變幾個不同的屬性以模擬此效果。粒子會以高速開始移動,然后因為它遠離爆炸中心,速度會馬上降低。當然,它的顏色也會由開始的亮到暗,最終完全消逝。最終,在它的生命周期中減小粒子尺寸能夠產生火焰在燃料耗盡時擴散的效果。

實現

首先,創建默認粒子系統對象(menu: GameObject -> Effects -> Particle System),然后到它的 Shape模塊並設置 shape為 Sphere(radius:0.5)。Standard assets中有一個 包含ParticleFireball材質的粒子很適合用於爆炸(Assets -> Import Package -> ParticleSystems)。你可以使用 Renderer模塊將這個材質應用於系統。因為 Renderer打開了,所以 Cast Shadows和 Receive Shadows應該關閉,因為爆炸火焰是發光而不是吸收光。

目前可以看到這個系統看上去就像是有很多 fireballs從一個中心點散發出來。當然,爆炸應該一次性產生許多粒子。在 Emission模塊,你可以設置 Rate值為0,並添加一個 Burst,時間為 0。在爆炸中的粒子數目由爆炸規模和強度決定,最初50就夠了。在 Particle System組件(與你的 GameObject同名),設置系統的 Duration和粒子的 Start Lifetime為 2秒。

你也可以使用 Size Over Lifetime模塊來構建火焰消耗燃料的效果。使用 "緩降"來設置size曲線(ie,size從100%開始並減少到0)。要使火焰暗淡並消逝,使用 Color Over Lifetime模塊,設置梯度:左邊從白色開始,右邊以黑色結束。Fire Add材質為渲染使用了額外的着色器,所以暗淡的顏色屬性也能控制粒子的透明度;因為顏色逐漸變為黑色,火焰將會變得完全透明。不僅如此,因為粒子會相互覆蓋,所以附加的材質允許粒子亮度“添加”在一起。這有助於當爆炸開始時,粒子靠得很近時的明亮閃光的效果。

就目前來看,爆炸已在形成,但它就像是在太空中發生的一樣。粒子在消失前被拋出,並以常速移動一段距離。如果你的game是在太空中,那么這可能就是你需要的效果。然而, 一場發生在大氣層內的爆炸將會被大氣抑制並放緩。使用 Limit Velocity Over Lifetime模塊並設置 Speed為 3.0,Dampen為0.4,你應該能看到爆炸強度變小了。

最后需要注意的是因為粒子將會遠離爆炸中心,它們的形狀會變得更易辨認。特別地,看到所有粒子都有相同的大小和旋轉,很明顯,每個粒子都重用相同的圖形。避免這種情況的簡單方法是為粒子的大小和旋轉增加一些隨機變化。在Particle System組件,點擊 Start Size和 Start Rotation右邊的小箭頭,設置為 Random Between Two Constants。對於旋轉,設置為 0 - 360,對於大小,設置 0.5 - 1.5。可以看到粒子圖形的重復不再那么明顯了。

用法

在測試階段,打開 Looping屬性,就可以反復觀看爆炸動畫。但是在最終game中,應該關閉此屬性。當一個有潛在爆炸可能性的物體(油箱)要設計爆炸時,你需要添加 Particle System組件到該物體上,且 Play On Awake屬性 disabled。這樣就可以根據需要從腳本中啟動爆炸效果。

    void Explode() {
        ParticleSystem exp = GetComponent<ParticleSystem>();
        exp.Play();
        Destroy(gameObject, exp.main.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();
    }

當爆炸實際上來源於一個在游戲中沒有實際表現的物體時(比如說,高速飛行的炮彈),你可以在合適的地方實例化爆炸。你可以從光線投射(raycast)中決定接觸點,比如說:

    // On the explosion object.
    void Start() {
        ParticleSystem exp = GetComponent<ParticleSystem>();
        exp.Play();
        Destroy(gameObject, exp.main.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);
        }
    }

從車輛產生煙霧

轎車和其他車輛都會產生煙霧,因為要將燃料轉化為動力。你可以使用 Unity的內置粒子系統來添加廢氣。

粒子時間線

煙霧是從排氣管中迅速冒出的,但在與空氣接觸后就會變緩。當它變緩后,就會傳播開來,並變得很模糊,直到消散在空氣中。因為派出的氣體很燙,當它穿過冷空氣時應該會上升。因為這些因素,想要構建真實效果,排煙粒子應該遵循以下規則:

  • 起始時,它不應該寬過管道,且隨着時間推移,會逐漸變大。
  • 起始時,它應該是部分透明,並且因為與空氣混合,會逐漸變為完全透明。
  • 從動力學角度看,粒子應該開始的很快且迅速變慢,同時會輕微上浮。

實現

Shape模塊

首先,設置 Shape為 Cone,Angle屬性為 0。“cone”實際上就是圓柱形管道。
接下來,Radius屬性值取決於車輪排氣管的大小。可以使用 Scene視圖中的 radius Gizmo來匹配車輛模型的排氣管半徑。半徑影響了許多屬性設置,比如說粒子半徑和發射率。本例假設的車輛為遵守 Unity標准尺寸約定的轎車,一個世界單位為 1米,因此半徑約為 0.05米。

Renderer 模塊

為了煙霧的可視化,Unity的 Standard Asset package包含了用於煙霧粒子的圖形。
設置 Renderer模塊的 Material屬性為 ParticleSmoke Materials。對於黑煙,使用 ParticleSmokeBlack,對於白煙,使用 ParticleSmokeWhite。

Main 模塊

默認的生命周期5秒對於排出的煙來說太長了。 Main模塊就是 Particle System組件最上面的那個模塊,其名字與 GameObject相同。在這個模塊中設置 Start Lifetime 為2.5秒; Simulation Space為 world,當車輛移動時,world simulation space能讓煙霧環繞在它產生地的周圍。設置 Gravity Modifier為 -0.1,負重力效果能導致煙霧粒子上升,就像它們是由熱氣組成的一樣。最后,點擊 Start Rotation右邊的小箭頭選擇 Random Between Tow Constants,設置值為 0-360。

Color over Lifetime 模塊

在這個階段,煙霧粒子看上去就較為真實了。下面就要令它能隨着時間消散。Enable並打開 Color Over Lifetime模塊,點擊 Color屬性的顏色選取器。在 Gradient Editor窗口,點擊右邊頂部,並設置alpha為0,頂部控制 alpha,底部控制顏色。現在你應該能看到煙霧粒子在 Scene中逐漸消散了。

Size Over Lifetime 模塊。

除了消散,煙霧還應該增加尺寸。Enable並打開 Size Over Lifetime模塊,點擊 Size曲線,在Inspector底部的曲線編輯器中將左邊的手柄垂直移動,使粒子起始大小等於實際大小的一小部分。你選擇的大小取決於排氣管,但是略大於管道能得到更好的效果。最后哦,使用Scene視圖中的粒子系統仿真來看看煙霧效果。

Force over Lifetime 模塊

最后,煙霧應該在它消散時變得緩慢。Enable並打開 Force over Lifetime 模塊。設置 Space為 Local。設置 力的 Z部分為負值,來表示力應該推動粒子回去(此系統在物體局部空間中沿 Z軸排出粒子)。本例使用 -0.75.

用法

在你確定排氣粒子系統的位置后,首先應該將它作為主車輛的子 GameObject。這能讓它跟隨車輛運動。對於只需要效果且沒有改變的簡單應用來說,你可以 enable Play On Awake和 Looping屬性。然而,你可能想要改變屬性,比如說排放率。改變排放率能提升真實性,因為引擎工作的越快,排放出的煙霧越多,但是他也會導致煙霧粒子傳播開來。一輛低排放率的高速車輛,就會產生明顯的“陣陣”煙霧效果,這極為不真實。
你可以從腳本簡單地改變排放率。如果你在腳本中有一個代表引擎轉速或車輛速度,你可以簡單地用一個常熟乘上此值,並將結果賦給 ParticleSyetem的 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;
        }

    }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM