Add Node : 將輸入 A 與 B 相加後輸出。可用在
Multiply Node : 將輸入 A 與 B 相乘後輸出。可用在
Split Node: 會將輸入向量 In 拆分為四個 Float 輸出 R、G、B 和 A。
這些輸出對應於輸入 In 向量的各個通道:
生成的程式碼
1 | float _Split_R = In[0]; |
參考: https://docs.unity3d.com/Packages/com.unity.shadergraph@17.0/manual/Split-Node.html
Transform Node: 用來將輸入從一個座標空間轉換到另一個座標空間。可以用來處理位置 (Position)、方向 (Direction) 或法線 (Normal) 等資料的變換。
當轉換的不是 Position(位置)時,Unity 建議使用 World 選項,而不要使用 Absolute World,否則可能會產生非預期行為。
例如,當轉換方向(Direction)或法線(Normal)時,Camera Relative(相機相對世界) 可能會影響計算結果,因此 World 會更適合。
參考: https://docs.unity3d.com/Packages/com.unity.shadergraph@17.0/manual/Transform-Node.html
對於計算機圖形學中的應用中,噪聲應該是偽隨機的,也就是說兩次調用應得到同樣的結果。
Gradient Noise (梯度噪聲): 梯度噪聲產生的紋理具有連續性,因此常用於模擬自然現象(如雲層、山脈、火焰等)。
Gradient Noise Node :梯度噪聲節點,根據輸入 UV 生成梯度噪聲(Gradient Noise)或 Perlin 噪聲(Perlin Noise)。
輸入
Simple Noise Node : 根據輸入的 UV 可以產生 簡單 (Simple) 或是 Value 雜訊。
參考:
UV Node : UV 節點 用來獲取頂點或片段的 UV 坐標。Unity 允許你在網格的數據中處理多個紋理座標集,因此可以透過 Channel 下拉選單來選擇從四組 UV 坐標中擷取資料。大多數網格通常只會使用 UV0,但你也可以利用其他通道來隱藏更多數據。
需要注意的是,Shader Graph 有一個限制,就是它只能存取 UV0 到 UV3,而 UV4 到 UV7 則只能在著色器程式碼中訪問。這意味著如果需要更多的 UV 通道,Shader Graph 本身無法直接處理,但你仍然可以在手寫的著色器代碼中處理更高的 UV 通道。
Position Node: 根據此節點所在的 Shader 階段 (Shader Stage)來決定,此節點是存取 網格頂點 (Vertex) 或片段 (Fragment) 的位置 (Position) 。
可以使用 Space (空間) 下拉選單來選擇輸出值的座標空間。
Ports
名稱 | 描述 | 類型 | 綁定 | 描述 |
---|---|---|---|---|
Out | 輸出 | Vector3 | 無 | 網格頂點 (Vertex) 或片段 (Fragment) 的位置 (Position) |
Controls
名稱 | 類型 | 選項 | 描述 |
---|---|---|---|
Space | 下拉選單 | Object, View, World, Tangent, Absolute World | 為這個 Position 節點的輸出選一個座標空間(coordinate space) |
World 與 Absolute World
Position 節點 提供 World (世界) 和 Absolute World (絕對世界) 兩種座標空間選項:
不同渲染管線的 World 預設行為:
舊版本
參考: https://docs.unity3d.com/Packages/com.unity.shadergraph@7.1/manual/Position-Node.html
Tiling And Offset Node(平鋪與偏移節點): Tiling And Offset Node 用於調整紋理(Texture)或 UV 坐標的平鋪(Tiling)和偏移(Offset),允許你在 Shader Graph 中動態改變紋理的大小與位置。
UV * Tilling
UV + Offset
UV 乘以一個數值就是縮放 (Tiling)
UV 加減一個值,就是移動 (Offset)
產生的程式碼
1 | void Unity_TilingAndOffset_float(float2 UV, float2 Tiling, float2 Offset, out float2 Out) |
Absolute Node : 將 輸入 取絕對值後 輸出。
Power Node : Power Node 就是次方的意思,當輸入 A 、 B, 輸出為 A的B次方, A^B
1 | void Unity_Power_float4(float4 A, float4 B, out float4 Out) |
Sample Texture 2D :
在 SpriteRenderer 有時候會有 Material does not have a _MainTex texture property. It is required for SpriteRenderer 的警告,這表示 你的 Shader 沒有 _MainTex 屬性。可以這麼理解:在 Shader Graph 中,如果你設定了一個 Texture2D 屬性,並將它的 Reference 設為 _MainTex,那麼,當這個 Shader 被應用到 Sprite Renderer 的 Material 上時,Sprite Renderer 會自動把它的 Sprite 貼圖傳遞給 _MainTex。這樣 Shader 就能正確使用 Sprite 的貼圖,而不需要手動指定 Texture。
Time Node (時間節點) : 用來提供 時間資訊
當希望物件可以持續的動,或者 Shader 需要依賴時間來運作時,就可以使用 Time 節點,可以嘗試使用 Time 節點
來做 動畫漸變(Gradient)
、顏色(Color)
、紋理(Texture)
,以創造獨特的 Shader 效果。
下圖是一個簡單的使用方式,如果你想要產生 0 到 1 之間循環的數值,可以這樣做。
參考:
如果 Mac 本機的容量不足,但是應用程式卻需要固定路徑才能使用,此時可以使用 symbolic link ,將原來的位置指向到另外一個位置。
以 DiffusionBee 為例,他的資料夾位置是在 ~/.diffusionbee
,我們可以把這個資料夾指向到外部硬碟的位置
mv
指令把 ~/.diffusionbee
移動到外部硬碟位置mv ~/.diffusionbee '/Volumes/外部硬碟/bee/'
ln -s
將外部硬碟位置連接到 ~/.diffusionbee
ln -s /Volumes/外部硬碟/bee/.diffusionbe ~/.diffusionbee
如果需要再次更改,連接到其他硬碟的話,只需要使用 rm
指令刪除原來鏈結,再次建立即可rm ~/.diffusionbee
ln -s /Volumes/另一個外部硬碟/bee_new/.diffusionbee ~/.diffusionbee
參考: https://michaelcharl.es/aubrey/en/code/diffusionbee-on-external-storage
Docker 筆記,記錄一些在使用上遇到的問題
拉取 Image 時出現 Error: creating build container: short-name "tomcat:9.0.20-jdk8-slim" did not resolve to an alias and no unqualified-search registries are defined in "/etc/containers/registries.conf"
因為 Docker Hub 不希望你拉錯 Image ,使用 UNQUALIFIED IMAGE NAMES 時可能會拉到攻擊者的 Image ,所以 Docker Hub 要你明確指定來源
解決方式是
podman pull docker.io/tomcat:9.0.20-jdk8-slim
而不是 podman pull tomcat:9.0.20-jdk8-slim
本文記錄如何在 Unity 中使用內建的 Unity Test Runner 進行 Unit Test。 。
首先選擇 Window
-> General
-> Test Runner
開啟 Test Runner
。
到 Test Runner
中找到 Create a Test new Assembly Folder in the active path.
按鈕,按下。
按下後會建立一個 Tests 資料夾,裡面會幫你建立一個 Tests.asmdef
檔案,這個檔案是 Unity 的 Assembly Definition File (程序集定義文件),讓你可以管理測試腳本的組件。
之後,為了讓測試腳本知道你寫的腳本,你需要在你放腳本的地方(如 Asserts/Scripts) 建立一個 Assembly Definition File (Create
-> Scripting
-> Assembly Definition
), 並取為自己想要的名稱,這邊命名為 MyScriptAssembly。
注意,如果你有使用 TextMeshPro 或是 DOTween 的話,你還需要在 MyScriptAssembly 中的 Assembly Definition References 加入 Unity.TextMeshPro 和 DOTween.Modules (預設不會有 DOTween.Modules,請參考 建立 DoTween 的 asmdef 檔案)。
接著回到 Tests.asmdef
檔案,將 MyScriptAssembly 加入到 Tests.asmdef
的 Assembly Definition References 中。
最後你就可以在 Unity 中開始使用 Unit Test
了,到 Tests 資料夾中,選擇 Create
-> Testing
-> C# Test Script
建立測試腳本。此外,你也可以在 Tests 資料夾中建立其他資料夾規劃你的測試。
建立測試腳本
1 | public class NewTestScript |
到 Test Runner
就可以看到測試了,可以一個一個選擇執行,或是執行全部。
一些注意事項:
如果要測試拋出例外之類的測試的話,需要使用 LogAssert.Expect
而不是 Assert.***
1 | // 測試錯誤日誌 |
SetUp 與 TearDown
1 | private class TestObject : MonoBehaviour { } |
一般預設是不會有 DoTween 的 asmdef 檔案,必須到 Tools
-> Demigiant
-> DOTween Utility Panel
中,開啟 DOTween Utility Panel
並找到 Create ASMDEF
按鈕 ,按下建立 asmdef 檔案。
使用粒子系統(Particle System) 製作 2D 煙霧效果
首先需要一張煙霧圖片,這邊使用 Photopea 來製作做煙霧圖片,
進入 Photopea 後,選擇 檔案
-> 新增
, 會彈出新增專案畫面。
選擇 檢視
-> 顯示
-> 格線
。啟用格線,方便我們之後對齊
選擇 編輯
-> 選項
打開選項畫面,調整格線大小,由於 寬高是 512 ,我們想要切為四等分,因此設定網格間隙為 512 / 4 = 128
接著選擇 濾鏡
-> 渲染
-> 雲彩
。 建立一個雲霧的圖片
再建立一個新專案,寬高一樣是 512 , 但是這次背景選 透明
回到有雲彩圖片的專案,選擇套索工具,羽化設為 20
px , 使用 套索工具 切出煙霧圖案
按下 ctrl
+ c
將切出的圖案複製 , 切換到 背景透明
的專案,按下 ctrl
+ v
貼上。可以使用移動工具,移動煙霧圖片,對齊中心。 如下圖:
最後,輸出煙霧圖片為 PNG
至此,我們的煙霧圖片就準備完畢了。
接著到 Unity 編輯器中。將煙霧圖片複製到裡面
建立一個 Material,命名為 SmokeMaterial
將 SmokeMaterial 的 Shader 更改為 Particles/Unlit
Surface Type
設為 Transparent 。設為透明。Surface Inputs
中 Base Map
設為剛剛的煙霧圖片。建立一個 GameObject ,命名為 Smoke
。接著在這個物件下建立一個 Particle System , 命名為 Smoke Particle System
。
以下開始設定 Smoke Particle System ,
Transform 組件
修改以下模組
主模組
Start Life Time
: 設為 Random Between Two Constants, 2 和 5Start Speed
:設為 Random Between Two Constants, 3 和 4Start Rotation
:設為 Random Between Two Constants, -180 和 180Scaling Mode
: Hierarchy 。 讓粒子系統可以直接隨父級物件縮放。Emission 模組
Rate over Time
: 40 。 每秒生成的40個粒子。Shape 模組
Shape
: Cone 。Color over Lifetime 模組
Texture Sheet Animation 模組
Mode
: Grid 。確保煙霧圖片已經被切割為 2×2 的動畫格,這樣才能正確使用 Grid 模式來播放動畫。Tile
: 圖片是 4 個,因此 X, Y 設為 2X
: 2Y
: 2Animation
: Whole Sheet 。 整張圖片Time Mode
: LifeTimeFrame over Time
: 選擇 Random Between Constants , 數字填 0 和 3Renderer 模組
Material
: 更改為上面建立的 SmokeMaterial最後效果如圖
在 2D世界中使用粒子系統 (Particle system) 碰撞物體
使用粒子系統 (Particle system) 產生粒子,並讓粒子與其他物件碰撞。可以用來製作粒子推動其他物體的效果,
首先建立一個 GameObject , 依自己需要取名(這邊取名 WindObject )
在這個 GameObject 之下建立一個 Particle system (Effects
-> Particle system
) ,依自己需要取名(這邊取名 WindEffect )
修改以下模組參數:
主要模組中的Duration
: 1 , 設定粒子系統的持續時間。設為 1 意味著粒子系統的 一次發射周期持續 1 秒。
Start Lifetime
: 0.5 , 每個粒子的生命週期(以秒為單位)。 設為 0.5 表示每個粒子在生成後僅存活 0.5 秒。當生命週期結束時,粒子將被銷毀。如果 Start Lifetime 設置為隨機範圍,則每個粒子會有不同的存活時間。Start Speed
: 2 , 粒子生成時的初始速度(以單位/秒為單位)。 設為 2 表示粒子從生成位置以每秒 2 單位的速度移動。Gravity Source
: 2D Physics 。 設為 2D Physics 表示粒子受到 Unity 2D 重力場的影響,會根據 Unity 2D 的 Physics2D.gravity 設定進行模擬。Simulation Space
: World 。 設為 World 表示粒子生成後會與世界空間對齊,並且粒子位置不會受到粒子系統的移動影響。Scaling Mode
: Hierarchy 。 Hierarchy 模式指的是粒子系統會根據其所在的父級物件及其整個層級結構的縮放來影響粒子的大小、速度、壽命等屬性。讓粒子系統可以直接隨父級物件縮放,無需手動調整。Max Particles
: 10 。 粒子系統同一時間允許存在的最大粒子數。設為 10 表示在任何時刻,粒子系統內的粒子數不會超過 10 個。
Emission 模組Rate over Time
: 10 。 每秒生成的粒子數量。設置為 10 意味著粒子系統會在每秒內均勻生成 10 個粒子。
Shape 模組Shape
: Edge 。 粒子會沿著一條 邊線(Edge) 發射,而不是從一個平面或三維體積中生成。Radius
: 0.1 。 當 Shape 設為 Edge 時,Radius 表示該邊線的長度(在視覺上呈現為一小段線段)。
Force over LifetimeX
: -20 。 表示粒子在 X 軸方向 持續受到 -20 的力,造成向左的運動。Y
: -5 。 粒子會向 負 Y 方向 持續加速,模擬下墜或重力效果。Z
: 0 。 表示粒子在 Z 軸方向 不受任何外力影響。Space
: World 。 表示所有的力都基於 世界空間,而非粒子系統的局部空間。
Color over Lifetime 模組Color
: 將後段設為透明,讓粒子發射後逐漸變透明。
Size over Lifetime 模組Size
: 指定粒子的大小如何隨著其生命週期從生成到消亡逐漸改變,將它設為一開始小後面變大的曲線,
Collision 模組Type
: World 。 讓粒子會與世界空間中的物理對象(如場景中的碰撞器)發生碰撞,而不是局限於粒子系統本身。Mode
: 2D
Render 模組Material
: 用於指定粒子的材質,從而決定粒子的顯示樣式。
以下說明如何在 Unity 中使用 Google AdMob
Edit
-> Project Settings
-> Package Manager
,輸入以下資料並儲存1 | Name: OpenUPM |
Window
-> Package Manager
開啟 Package Manager
,找到 Google Mobile Ads for Unity
並按下 Install 安裝。Project Settings
-> Player
-> Android
-> Publishing Settings
-> Build
確認 Custom Gradle Properties Template
和 Custom Gradle Settings Template
有被勾選。
Assets
-> External Dependency Manager
-> Android Resolver
-> Resolve
,讓 Unity External Dependency Manager 程式庫將已宣告的依附元件複製到 Unity 應用程式的 Assets/Plugins/Android
目錄中。Assets
-> Google Mobile Ads
-> Settings
,設定 AdMob 應用程式 IDMobileAds.Initialize()
讓應用程式初始化 Google Mobile Ads SDK。初始化只需執行一次,最好是在應用程式啟動時執行。1 | public class LoadGoogleMobileAdsScript : MonoBehaviour |
1 |
|
Banner Ad
)BannerView
類建立橫幅廣告 1 | // _adUnitId :BannerView 應從中載入廣告的廣告單元 ID。 |
1 | if (bannerView != null) |
1 | public class BannerAd : MonoBehaviour |
Reference:
Unity 的 AuidoMixer 可以讓開發者將遊戲音樂,音效分組,方便管理。
以下說明如何設定。
Create
-> Audio
-> AudioMixer
, 建立一個 AudioMixerMainAudioMixer
+
, 建立兩個分組並命名為 Music
和 SoundEffect
SoundEffect
而 BackgroundMusic 的 Group 設為 Music
MainAudioMixer
物件,把它展開,會看到建立的 Group ,選擇 Music ,在 Inspector 上面,找到 Volume ,對著 Volume 按下滑鼠右鍵,選 Expose Volume (of Music) to script
。 SoundEffect 也是同樣的操作audioMixer.SetFloat
變更數值的話,傳入名稱要一致才行。1 | using UnityEngine; |
audioMixer.SetFloat
接受的是分貝值範圍(20f
為最大,-80f
為最小),如果希望使用範圍為 0 ~ 1 的線性值,可透過 Mathf.Log10
進行轉換。float dB = value > 0 ? Mathf.Log10(value) * 20 : -80f;
Reference: