Shader Graph 筆記大綱

  1. Shader Graph 的 Space:在 Shader Graph 中,Space(空間)是指資料在不同坐標系統中的表示方式。不同的空間決定了資料如何被處理和顯示,對於著色器的效果有著重要的影響。Shader Graph 中常見的空間類型有:Object Space、World Space、View/Camera Space、Tangent Space 和 Clip Space。
  2. Shader Graph Block Nodes:在 Shader Graph 中,Block Nodes(區塊節點)是組成著色器的基本元素。每個區塊節點代表著一個特定的資料處理功能,這些區塊節點可以在 Master Stack 中組合,最終輸出到著色器的結果。這些節點會處理像是頂點、法線、顏色、光照等屬性,並控制著色器的行為。
  3. Shader Graph Properties : 在 Shader Graph 中,Properties (屬性)是用來設定和控制著色器的外部變量,這些變量可以從 Unity 的材質面板中進行調整,並影響著色器的輸出。這些屬性讓你在不修改 Shader Graph 設定的情況下,動態改變材質的外觀。它們通常用來創建可調整的材質效果,並且可以進行繫結到 Shader Graph 中的不同節點,以控制最終渲染結果。
  4. Shader Graph Nodes :Shader Graph Nodes 是 Shader Graph 中的組件,每個節點都有特定的功能,並且可以連接到其他節點來實現所需的效果。這些節點提供了創建圖形效果所需的數學計算、變換、顏色處理、貼圖采樣等操作。
  5. Shader Graph 入門 : 這篇教學使用 Shader Graph 建立了一個簡單的 Shader,讓 Sprite Renderer 在使用 Material 的時候,仍然可以用 Color 影響顏色。

粒子系統(Particle System)

粒子系統(Particle System)是一種用於模擬和渲染大量微小物件的技術,這些微小物件通常用於建立一些視覺效果,如火焰、煙霧、爆炸、流星、雨、雪等。

在 Unity 建立一個粒子系統的方式和建立其他組件的方式一樣,在編輯器中 Effects -> Particle System

粒子系統有多個模組和屬性可以使用,我們可以根據需要啟用某些模組。預設會啟用 EmissionShapeRenderer

模組 說明
Main 包含會影響整個粒子系統的全局屬性(global properties)。
Emission 控制粒子的發射速度,時間,波次
Shape 第一發射粒子的體積和形狀
Velocity over Lifetime 控制粒子在生命週期中的速度
Limit Velocity over Lifetime 在生命週期內限制粒子的速度
Inherit Velocity 控制粒子的速度如何隨時間推移而受到其父物件移動的影響
Lifetime by Emitter Speed 用來控制粒子系統中每個粒子的生命週期如何受到發射器速度的影響。
Force over Lifetime 通過此模組中指定的力來對粒子產生影響
Color over Lifetime 指定粒子的顏色和透明度在其生命週期中如何變化
Color by Speed 設定粒子的顏色根據粒子速度(每秒的距離單位)變化
Size over Lifetime 控制粒子在其生命週期內的大小
Size by Speed 設定粒子的大小,根據粒子速度(每秒的距離單位)變化
Rotation over Lifetime 控制粒子在其生命週期內的旋轉
Rotation by Speed 設定粒子的旋轉,根據根據粒子速度(每秒的距離單位)變化
External Forces 修改力對粒子的影響
Noise 未粒子添加噪音值
Collision 控制粒子如何與場景中其他遊戲物件發生碰撞
Triggers 控制粒子的觸發事件
Sub Emitters 在某粒子生命週期的階段建立附加粒子發射器
Texture Sheet Animation 控制動畫幀進行播放
Lights 控制粒子的光照
Trails 控制粒子的軌跡(拖尾)
Custom Data 在編輯器中定義要附加到粒子的自訂資料格式
Renderer 設定粒子的圖案或網格如何被其他粒子變換,著色和繪製

Reference:

時間(Time)與幀(Frame)

Unity 中有一個 Time 類(class),它提供了與時間相關的重要方法,讓你可以在專案中使用。


在 Unity 中,有兩個追蹤時間(track time)的系統,一個是每步之間的時間量是可變的,另一個是每步之間的時間量是固定的。

  • 可變時間步長(variable time step)系統:在每次繪製畫面和運行你的APP或遊戲程式碼時執行一次。
  • 固定時間步長(fixed time step)系統:以預定義的時間步長前進,並且與畫面的更新無關。這個系統通常與物理系統相關聯,物理系統會按照固定時間步長的速率運行,但你也可以在每個固定時間步長中執行自己的代碼。

可變動幀率(Variable Frame Rate):在 Unity 中每一幀所執行的時間會因為程式碼複雜度或是顯示畫面的複雜度而有所不同,同時也會受到裝置設備的效能影響。

固定時間步長(Fixed Timestep):在 Unity 中,它的物理系統使用固定時間步長(Fixed Timestep),防止突然出現物體在一幀內移動非常大距離的狀況。

Unity 的時間邏輯流程圖:此文將說明 Unity 是如何處理時間的。

Time 類屬性在幀率變化中的範例:在此文中將說明 Time 類中的各屬性是如何處理突如其來的幀率大幅變動。

錄製遊戲影片:錄製遊戲影片是時間管理中的一個特例。保存螢幕圖片的操作需要耗費相當多的時間,這會導致遊戲的正常幀率降低,錄製出的影片無法反映遊戲的實際表現。為了解決這個問題,可以使用 Unity 提供的 captureFramerate 屬性,來調整錄製時的幀率。

一個簡單的技能冷卻計時器:將示範如何使用 Time.deltaTime 來製作技能冷卻時間。


Time 類有以下 static 屬性

captureDeltaTime 減慢你APP的播放時間(playback time),以便 Unity 能夠在幀與幀之間保存截圖。
captureFramerate Time.captureDeltaTime 的倒數(reciprocal),即 1/captureDeltaTime
deltaTime 從上一個幀到目前幀之間的時間間隔,單位是秒 (只可讀)
fixedDeltaTime 固定間隔幀時間
fixedTime 從遊戲開始到現在 FixedUpdate 進行的時間,以秒為單位 (只可讀)
fixedTimeAsDouble fixedTime 相同,但是是 double 型態 (只可讀)
fixedUnscaledDeltaTime 每次 FixedUpdate 之間的固定時間間隔,以秒為單位,且不受timeScale影響(timeScale-independent)。(只可讀)。這表示調整timeScale時(如暫停遊戲),它的值也不受影響
fixedUnscaledTime 表示從遊戲開始以來經過的時間,以固定的時間間隔計算,並且不受 timeScale 影響 (只可讀)。
fixedUnscaledTimeAsDouble 與 fixedUnscaledTime 相同,但是是 double 型態 (只可讀)
frameCount 遊戲開始以來的總幀數 (只可讀)
inFixedTimeStep 如果在 fixed time step callback 中將返回 true 例如MonoBehaviour 的 FixedUpdate,否則返回 false 。(只可讀)
maximumDeltaTime 任何給定的幀中 Time.deltaTime 的最大值. 用來限制兩個幀之間的時間(Time.time)增加,以秒為單位。
maximumParticleDeltaTime 在一幀中可以花在更新粒子(particle)的最大時間。如果在一幀中超過這個時間,那麼就會把這個更新分割為多個較小的更新。
realtimeSinceStartup 它返回從APP啟動到當前時間所經過的時間(以秒為單位)。也就是說,它計算了從APP啟動以來的總實際時間,而不僅僅是應用程序在前台運行的時間 (只可讀)
realtimeSinceStartupAsDouble realtimeSinceStartup 相同,但是是 double 型態 (只可讀)
smoothDeltaTime 一個平滑的 Time.deltaTime (只可讀)
time 從APP開始執行到目前這一幀的總時間長,以秒為單位 (只可讀)
timeAsDouble time 相同,但是是 double 型態 (只可讀)
timeScale 時間流逝的縮放程度,可以用在實現慢動作效果,預設為 1.0 。 當為 1.0 時,表示遊戲時間和真實時間同步,如果設為 0.5 則遊戲時間以半速運行。當為 0 時,則時間停止,但是遊戲邏輯(像是 Update 方法仍然會被呼叫)與渲染事件仍然會被觸發。
timeSinceLevelLoad 自從最後一個非附加場景(non-additive scene)載入完成以來的時間 (以秒為單位)
timeSinceLevelLoadAsDouble timeSinceLevelLoad 相同,但是是 double 型態 (只可讀)
unscaledDeltaTime 自上一幀以來經過的時間(以秒為單位),並且不受 Time.timeScale 影響 (只可讀)
unscaledTime 自遊戲開始以來經過的總時間(以秒為單位),這個時間不受 Time.timeScale 的影響
unscaledTimeAsDouble unscaledTimeAsDouble 相同,但是是 double 型態 (只可讀)

Reference:

閱讀Level Up Your Code With Game Programming Patterns

這本 Unity 的電子書《Level up your code with game programming patterns》 對於提升遊戲開發者的程式設計能力非常有幫助。
以下是該電子書的網址與Github
網址:https://blog.unity.com/games/level-up-your-code-with-game-programming-patterns
Github:https://github.com/Unity-Technologies/game-programming-patterns-demo/tree/main


這本書介紹了工程師必須了解的SOLID 原則(SOLID principles),這些原則是編寫高質量程式碼的基礎,SOLID原則是以下五大原則的簡稱:

  • 單一職責原則(Single responsibility):確保類只負責一件事。
  • 開閉原則(Open-closed):在不更改現有程式碼的情況下,可以擴展一個類的功能。
  • 里氏替換原則(Liskov substitution):子類可以替代基類,而不影響程式的正確性。
  • 介面隔離原則(Interface segregation):讓介面(interface)盡可能簡單,確保實作類只需要實作其所需的介面方法。
  • 依賴倒置原則(Dependency inversion):高層模組不應依賴於低層模組,兩者都應依賴於抽象。具體實現應依賴於抽象,而不是抽象依賴於具體實現。

這些原則可以讓你的程式設計更具彈性和可維護性,但在不確定是否要使用它們時,請記住KISS(Keep It Simple, Stupid)原則,不要強迫將其應用於程式碼中。


這本電子書也介紹了以下常用在遊戲開發中的設計模式