鴨仔開發日記

一個開發者的點點滴滴 – ABOUT A GAME DEVELOPER


  • 首頁

  • 彙整

  • 系列文章

  • 閱讀筆記

  • 關於

[Unity] Rendering 相關的 Event Functions 筆記

發表於 2018-06-21 | 分類於 game-develop , unity |

很多渲染套件或特效都會用上 OnPostRender 或 OnRenderImage 等,是一般 GameObject 上撰寫遊戲邏輯時較少用到的事件。

最近在大量處理著與畫面相關的項目,感到對這些事件不夠熟悉,於是重新讀過一些資料,留些筆記備忘。

閱讀全文 »

[Unity] 從零開始的學習心得 #5 – Mesh 與 Material

發表於 2018-05-12 | 分類於 game-develop , unity |

unity-learning-totally-review-5

此篇文章是《從零開始的 Unity 學習心得》系列的第五篇文章,這個系列是記錄我對 Unity 的開發及學習心得,包含我用何種方式去理解 Unity 的運作,並且在我所知的範圍內盡可能說明相關原理與開發要點。完整系列的目錄可以參考:

  • [Unity] 從零開始的學習心得 #0 – 起頭 & 目錄
閱讀全文 »

[Json.NET] DeserializeObject 檔案字串時遇到的錯誤 (Solved)

發表於 2018-04-11 | 分類於 coding |

ZERO WIDTH NO-BREAK SPACE

今天在使用 Json.NET 處理讀取到的 Json 文字檔案,要反序列化為 Object 物件資料時遇到了一個錯誤:

1
Unexpected character encountered while parsing value: e. Path '', line 0, position 0.

後來找出了原因並解決了,是關於檔案在某些文字編輯器儲存時會留下的 BOM 字元,導致 Json 格式錯誤。

閱讀全文 »

[WebGL] three.js 學習筆記 #2 - 初見PBR

發表於 2018-02-28 | 分類於 game-develop , webGL |

red pbr

初淺地研究,嘗試自行撰寫 Physically Based Rendering shader。目前 javascript 用的還不是很習慣,非同步與事件順序常常會轉不過來,但 WebGL 作為一個練習寫 shader 的環境來說還是相對方便的。

閱讀全文 »

[WebGL] three.js 學習筆記 #1

發表於 2018-02-24 | 分類於 game-develop , webGL |

前陣子在找四元樹與八元樹的資料,發現了 three.js 這個套件,被用於做四元樹相關演算法的圖像展示。

three.js 是一個重新封裝 WebGL 語法的一個 javascript library,大幅降低開發 WebGL 的難度,之前有簡單接觸過 OpenGL,這次趁著週末便來挑戰看看 WebGL 吧!

閱讀全文 »

[Unity] 從零開始的學習心得 #4 – Unity 與外部資源

發表於 2018-02-03 | 分類於 game-develop , unity |

unity-learning-totally-review-4

此篇文章是《從零開始的 Unity 學習心得》系列的第四篇文章,這個系列是記錄我對 Unity 的開發及學習心得,包含我用何種方式去理解 Unity 的運作,並且在我所知的範圍內盡可能說明相關原理與開發要點。完整系列的目錄可以參考:

  • [Unity] 從零開始的學習心得 #0 – 起頭 & 目錄
閱讀全文 »

[Unity] 從零開始的學習心得 #3 – 物理系統的陷阱

發表於 2018-01-20 | 分類於 game-develop , unity |

unity-learning-totally-review-3

此篇文章是《從零開始的 Unity 學習心得》系列的第三篇文章,這個系列是記錄我對 Unity 的開發及學習心得,包含我用何種方式去理解 Unity 的運作,並且在我所知的範圍內盡可能說明相關原理與開發要點。完整系列的目錄可以參考:

  • [Unity] 從零開始的學習心得 #0 – 起頭 & 目錄

上篇文章說明了幾個 Unity 的基本組成,並且開始接觸 MonoBehaviour。這篇文章將延續話題,聊聊我對於 Unity 物理系統 – 一個最常用在與 MonoBehaviour 共築遊戲邏輯的系統 – 的理解。

閱讀全文 »

[Unity] 從零開始的學習心得 #2 – Unity 的基本組成

發表於 2018-01-19 | 分類於 game-develop , unity |

unity-learning-totally-review-2

此篇文章是《從零開始的 Unity 學習心得》系列的第二篇文章,這個系列是記錄我對 Unity 的開發及學習心得,包含我用何種方式去理解 Unity 的運作,並且在我所知的範圍內盡可能說明相關原理與開發要點。完整系列的目錄可以參考:

  • [Unity] 從零開始的學習心得 #0 – 起頭 & 目錄

這次主要重點放在 場景、物件、組件 的關係,以及撰寫 MonoBehaiour 腳本時可能會用上的一些經驗談。

閱讀全文 »

[Unity] 從零開始的學習心得 #1 – 遊戲如何動起來

發表於 2018-01-03 | 分類於 game-develop , unity |

unity-learning-totally-review-1

此篇文章是《從零開始的 Unity 學習心得》系列的第一篇文章,這個系列是記錄我對 Unity 的開發及學習心得,包含我用何種方式去理解 Unity 的運作,並且在我所知的範圍內盡可能說明相關原理與開發要點。完整系列的目錄可以參考:

  • [Unity] 從零開始的學習心得 #0 – 起頭 & 目錄

在開始深入 Unity 之前,我會建議先有點撰寫程式的概念。而這篇文章會先說明,遊戲程式與一般學習程式語言時撰寫的單次性程式的差異:遊戲迴圈。

閱讀全文 »

[Unity] 從零開始的學習心得 #0 – 起頭 & 目錄

發表於 2018-01-03 | 分類於 game-develop , unity |

unity-learning-totally-review

我初次接觸 Unity 是在 2015 年 9 月左右,當時沒有任何做遊戲或互動媒體的經驗,一個基本只會 C++ 跟一點 Web 開發的畢業生加入了遊戲公司,從沒聽過 Unity 也沒寫過 C# 開始,一路學習到現在。

一路上依賴網路自學,拆解公司舊專案當參考,追趕新專案的需求,在去年 2016 的 4月前後,接觸了 Unity 相關的網路社群 (Unity 應用領域、You can make game),開始了大量吸趴的一年。

如今又過了一年,雖然憑著兩年實作經驗可能還只能算隻小菜鴨,更多深入專精的遊戲開發技術也尚未掌握起來,而這篇文章是想寫下到目前為止,我學習 Unity 的過程與理解。

因為我是從已經有程式底子的情況來學習 Unity,所以這系列的內容會有較多的程式視角,但我會盡量從沒基礎的角度進行補充,作為一個基本觀念的系列文章。

如果這系列文章,可以作為某人進入遊戲開發的敲門磚,我想便足矣。

閱讀全文 »

開始 Hexo

發表於 2017-12-29 |

這是第一篇用 Hexo 發佈的文章,用來熟悉操作,並隨便紀錄點心得。

本來我用來寫文章的部落格是使用 Wordpress,是一個用 php 及 SQL 資料庫建構的部落格系統。後來有了建立靜態網站的需求,才抱著嘗試的心態研究 Hexo,結果一試成主顧。

除了 Hexo 之外還有不少靜態部落格框架,選擇了 Hexo 的主要因素是它用 Node.js 作為開發語言,相對容易在 Windows 跟 Mac OSX 上建立共通的開發環境。

閱讀全文 »

[Unity] 利用 UI 元件製作雷達圖

發表於 2017-12-02 | 分類於 game-develop , unity |

前幾天用 Unity 的 uGUI 元件組合出了雷達圖效果,同時也能夠及時的修改數值,表現在圖表上,是個蠻有趣的嘗試。

如果要完整表達內容,可能要搭配大量的圖片,所以這次嘗試使用影片的方式來分享實作。

閱讀全文 »

[C#/Unity] 這不叫 Singleton,叫 Service Locator

發表於 2017-11-05 | 分類於 coding |

過去在《[C#/Unity] 更多 Singleton – More Singleton in Unity》這篇文章中,實作了一個名為 Singleton manager 的物件來做 Singleton 的註冊與使用。

但最近在研讀 相依性注入 (Dependency Injection) 相關文章時,才發現有個叫做 Service Locator 的設計模式,基本上就是我過去所實作的 Singleton manager。再加上一些關於抽象化的觀念又比當初更成熟了,因此便想趁機改善當初的設計,同時正名為 Service Locator。

閱讀全文 »

[筆記] Review of Unite Europe 2017 – Squeezing Unity

發表於 2017-11-02 | 分類於 note |

這是看 Unity 官方 Youtube 頻道的影片後,留下來的筆記。

相關連結:

  • 影片 – Unite Europe 2017 – Squeezing Unity: Tips for raising performance
  • 投影片 – Unite Amsterdam 2017 – Squeezing Unity

outline

閱讀全文 »

[雜談] 聊聊奧特曼,再扯一點數位市場的變化

發表於 2017-10-31 | 分類於 indoor-life |

最近有在看最新的奧特曼影集《奧特曼Geed》,同時也回頭重看了小時候最後看過的《奧特曼蓋亞》。

這周《奧特曼Geed》第 17 集到了一個劇情階段,剛好《奧特曼蓋亞》也幾乎全部看完了,也看了不少網路上的討論,突然便想來寫篇文章抒發想法。

geed post

閱讀全文 »

[學習心得] OpenGL 線上課程 - Review OpenGL Online Course

發表於 2017-09-22 | 分類於 game-develop , openGL |

將 《Modern OpenGL C++ 3D Game Tutorial Series》這個 OpenGL 的線上課程完結了,比起預計所花的時間短了不少。 OpenGL 是個發展已久的 Graphics API,當遊戲光靠 CPU 已經無法負擔,需要透過 GPU 來 “硬體加速” 畫面處理的工作時,相對的溝通工作便可以用這類 API 來完成。 雖然還有其他 Graphics API,但我選擇了 OpenGL 作為入門,並碰巧遇上了這門線上課程的優惠。完成了課程後,在這邊記下一些心得,讓其他想接觸 OpenGL 或這門線上課程的人作為參考。

課程內容

一路下來這個課程可以學到:

  • Windows 與 Mac OSX 上 OpenGL 的開發環境架設
  • 建立 shader program 到 GPU 上
  • 傳遞 mesh 資料至 GPU 並透過 shader 繪製到畫面上
  • 將圖片、貼圖載入到 GPU 的 TEXTURE Unit 中使用
  • 位移、旋轉相關變形的實作
  • 虛擬攝影機、動態取景的實作
  • 傳遞相關資料並使用 shader 渲染光照效果
  • 利用第三方 library 讀取 model 檔案至程式中繪製
  • Skybox 簡單實作

不過這個課程並不會詳細解說每個項目背後的原理,包括每個使用到的 OpenGL API 的細節功能也不會清楚的解釋,基本上就是把課程內容分別舉例子實作一次,並提供給大家原始碼做為參考。 上述的每個項目都是在 3D 繪圖、遊戲製作的一些基本需求,透過這個課程可以理解如何用 OpenGL 達成這些需求。 但是因為沒有描述原理,所以沒有 3D 繪圖的一些觀念時,會在講者編輯程式碼與解說時產生疑惑,變成知其然而不知其所以然的窘境,甚至鴨子聽雷的情況。

個人建議的先備知識

事前如果有 3D 繪圖的一些觀念,或者有細究過遊戲繪圖,上起這門課程會容易些:

  • 3D Model 資料的組成:mesh、vertex、triangle、normal、uv 貼圖等關鍵字的意義
  • Render pipeline:應用階段、幾何階段等繪圖步驟之間會傳遞甚麼資料
  • vertex shader 與 fragment shader 的功用與基本認識

這門課是用 C++ 為使用語言,所以當然對 C++ 要有一定程度的了解,包括類別 (class)、指標 (pointer)、標頭檔 (header file) 如何在 C++ 中使用,而不是只有條件是跟迴圈的程度。 另外如果先擁有撰寫 shader 的基礎 (Unity shaderLab 等任何 shader 實作手段都行),那基本上就沒問題了,否則最低限度至少要先知道 vertex shader 與 fragment shader 的意義。

其他感想

就個人感覺來說,如果是要做為初學者的教學,這段線上課程所包含的內容有點貧乏。許多的原理跟 API 細節沒有解說,會在課程剛開始時感到疑惑,必須另外去找資料或文件確認 API 的功能。 但是因為網路上自學 OpenGL 的影片相當少見,就這點來說還是相當值得的。比起慢慢地閱讀文件或文章,自行做實驗來學習,實際操作的影片可以更好的引導進入狀況,配合自己在每個小節後查資料解惑,很快就能對 OpenGL 掌握到一定程度。 利用這門課當作敲門磚,我自覺算是很順利地進入 OpenGL 的世界,未來只要再補上更多原理細節即可。 可以來想想要做些甚麼作品來當作練習,檢查自己的理解了。

[閱讀筆記] Unity のエディター拡張 #3

發表於 2017-07-19 | 分類於 game-develop , unity |

《Unity のエディター拡張》後所留下的簡單筆記,第九到十一章。 介紹了 CustomEditor,也就是最常被使用的 自訂 Inspector 操作介面,這幾個章節內容很多,我覺得介紹依舊尚淺而有些不明白。 CustomEditor 真是博大精深的領域!

第九章:CustomEditor

  • CustomEditor 是指 自訂 提供給 Component 顯示於 Inspector 與 SceneView 中的 編輯器。
  • Inspector 視窗可以切換 Normal / Debug 兩個模式,分成 GUI 顯示或者只列出 Serialize Field 欄位資訊。
  • 一般應用可以利用第二章介紹的功能自訂部分 Inspector 視窗。
  • 直接實作 CustomEditor 需要繼承 Editor 類別,並使用 CustomEditor (Type) 這個 Attribute 指定想要對應的 MonoBehaviour。
    • 自訂的 GUI 需透過 override 寫於 OnInspectorGUI 及 OnSceneGUI 兩個方法中。
    • base.OnInspectorGUI () 記得於 override 後進行呼叫。
  • 作為 Editor 存取 MonoBehaviour 的 Serialize Field 參數的手段:
    • 使用 Editor.serializedObject 來存取,透過 serializedObject.FindProperty() 來取得特定欄位。
    • 直接參照 MonoBehaviour,進行操作。
  • Undo 的實作:
    • EditorGUI.BeginChangeCheck / EndChangeCheck 檢查參數是否有變化。
    • Undo.RecordObject () 進行 Undo 序列的紀錄寫入。
  • 複選多個相同 Component 的情況:
    • CanEditMultipleObjects 是允許複數編輯的 Attribute。
    • 複數編輯是對多個 serializedObject 的存取與操作。
    • Editor.targets 可以取得被複選的 Component 實體,進行複數選取時的綜合介面實作。
    • EditorGUI.showMixedValue 用於標示接下來的欄位,不同 Component 的值相異,數值顯示會以橫槓 (ー) 表示。
    • 值的寫入需要用迴圈操作。
  • 用 PropertyDrawer 實作特定類別的編輯器:
    • 需要繼承 PropertyDrawer 類別,並使用 CustomPropertyDrawer (Type) 這個 Attribute 指定想要對應的 class。
    • OnGUI (Rect position, SerializedProperty property, GUIContent label) 是實作 GUI 的指定方法。
    • 透過 property.FindPropertyRelative 可以取得對性類別的 Serialize Field 資訊。
    • GetPropertyHeight () 必須 override 並回傳自訂編輯器的高度,才能正確的在 Inspector 上繪製。
    • base.GetPropertyHeight (property, label) 可取得依照 Serialize Field 數量計算的預設高度。
  • Inspector 下方的預覽窗:
    • Editor.HasPreviewGUI () 經過 override,會在回傳 true 時顯示預覽窗。
    • Editor.GetPreviewTitle () 用於實作標題。
    • Editor.OnPreviewSettings () 用於實作右上方按鈕。
    • Editor.OnPreviewGUI (Rect r, GUIStyle background) 用於實作窗口內容。
    • 透過 PreviewRenderUtility 進行場景的取景與渲染。
    • 如果需要單一物件的預覽:
      • 使用 Object.Instantiate 生成預覽用物件。
      • 物件設定為 HideFlags.HideAndDontSave。
      • 以 Camera.PreviewCullingLayer 為 cullingMask 進行 PreviewRenderUtility 的渲染。
    • Editor.OnInteractivePreviewGUI (Rect r, GUIStyle background) 用於實作可以互動 (旋轉物件) 的預覽窗。
  • 針對 Asset (而非腳本) 也可以實作 Editor 來增加對資源的支援。

第十章:PropertyDrawer

  • PropertyDrawer 是為特定類別設計,通用於所有相關應用的 Component 上, 顯示 Serialize Field 於 Inspector。
  • PropertyDrawer 除了對應類別,也可以對應到 PropertyAttribute 的實作。
  • 如果實作的 CustomGUI 跟預設的 GUI 高度不同,則必須實作 GetPropertyHeight() 的 override,Inspector 才能正確運作。
    • base.GetPropertyHeight() 會取得預設 GUI 的高度。
  • EditorGUILayout.Knob 本來不可用於 PropertyDrawer,但本章節使用了 Reflection 強制將這個 EditorGUI 用於 PropertyDrawer 上。
  • 本章的其他範例:
    • 連結參數到同一物件其他 Component 的資訊。
    • 讓對應欄位顯示 GUI 跟數值但無法編輯。
    • 讓 enum 的 popup menu 用指定字串代替數值。
    • 實作 int,string 等變數的 popup menu。
    • url 圖片預覽。
    • 用下拉選單選擇場景名稱存入 string 變數。

第十一章:ProjectWindowUtil

  • ProjectWindowUtil 用於處理在 Project 視窗創建資源、變更名稱等動作。
    • https://github.com/MattRix/UnityDecompiled/blob/master/UnityEditor/UnityEditor/ProjectWindowUtil.cs
  • ProjectWindowUtil.CreateAsset () 創建資源,並進入命名模式,與 AssetDatabase.CreateAsset 會直接定名不同。
    • 實際上內部呼叫了 StartNameEditingIfProjectWindowExists ()。
  • ProjectWindowUtil.StartNameEditingIfProjectWindowExists () 創建資源並進行更名動作。
    • EndNameEditAction 是更名動作需要的一個傳入參數,可用於自訂更名完畢的後續動作。
    • EndNameEditAction 需用 ScriptableObject.CreateInstance() 實體化。
  • 透過 ProjectWindowUtil 可以實作各種自訂資源的生成,並可以在命名後進行一些處理。

[閱讀筆記] Unity のエディター拡張 #2

發表於 2017-07-18 | 分類於 game-develop , unity |

《Unity のエディター拡張》後所留下的簡單筆記,第六到八章。 前五章以介紹內建的 Editor 功能為主,六到八章開始進入了自訂 EditorGUI 的部分了,然後是 EditorWindow。

第六章:EditorGUI

  • EditorGUI 與 EditorGUILayout 這兩個類別與 4.6 以前,用於遊戲 run time 建立使用者介面的 GUI 類別功能相近,只是它可被用於 EditorWindow 上。
  • 相關 API:
    • EditorGUI.BeginChangeCheck / EndChangeCheck 用於檢查是否有數值變化,有則回傳 true。
    • EditorGUI.BeginDisabledGroup / EndDisabledGroup 用於繪製無法操作的區塊。
    • EditorGUILayout.BeginFadeGroup / EndFadeGroup 可以裁切掉特定高度外的 UI 元件。
    • EditorGUI.ObjectField 可以產生欄位用於拉動資源形成參照,依照資源類型有不同介面。
    • EditorGUI.MultiFloatField 多欄位的浮點數組合。
    • EditorGUI.indentLevel 配合 EditorGUILayout 使用,用於調整縮排。
    • EditorGUILayout.Knob 繪製旋鈕。(疑?官方文件中沒有這個阿?)
  • 關於 Scope
    • 用於在特定的彈性範圍內控制 GUI 參數。
    • Scope 繼承了 IDisposable 介面,透過 using 來控制影響範圍。
    • 內建的 Scope 有 HorizontalScope、VerticalScope、ScrollViewScope,實際上利用 EditorGUILayout.BeginHorizontal/EndHorizontal 之類的 API。
    • 可以繼承 GUI.Scope 來自訂 Scope。
  • 小技巧:
    • 利用 Toggle 欄位配合 button 的 GUIStyle,可以做出放開滑鼠後不跳起的按鈕開關。
    • EditorStyles 中可以呼叫內建各式元件的 GUIStyle,做出各種外觀與功能的組合。

第七章:EditorWindow

  • EditorWindow 為 ScriptableObject 的子類別,可以透過 CreateInstance () 來產生類別,也允許複數個相同視窗存在。
  • 如果只允許單數視窗,可以利用 Singleton pattern 或者使用 EditorWindow.GetWindow () 這個 API。
  • 其他有關開啟 EditorWindow 的 API:
    • ShowUtility () 將使視窗無法被拖動成為 tab。
    • ShowPopup () 會使視窗沒有上方工具列 (關閉視窗的按鈕等),需自行實作關閉視窗的手段。
    • ShowAsDropDown () 如選單般會自動調整位置,保證視窗整體都在螢幕內顯示。
  • 其他視窗類別:
    • ShowAuxWindow 是與 EditorWindow.ShowUtility () 效果相同的一個視窗類別。
    • PopupWindowContent 是一個可以繼承並作為彈出視窗的類別。
    • ScriptableWizard 會自動為類別中的 Serialized Field 提供編輯欄位,並不使用 OnGUI 作為 GUI 設定。
  • PreferenceItem 是一個用於添加選項至設定視窗的 attribute,對應的方法中直接編寫 GUI。
  • IHasCustomMenu 是一個增加選項至視窗右上方 menu 的 interface。
  • 其他 API:
    • EditorWindow.minSize / maxSize 限制視窗的調整。
    • EditorWindow.titleContent 可以在標題處加上 icon。
  • 可用 Resources.FindObjectsOfTypeAll 取得其他視窗實體。
  • 因為 EditorWindow 是 ScriptableObject 的子類別,所以可以在腳本的 inspector 窗口設定 Serialized Field 的預設值。

第八章:MenuItem

  • MenuItem 是一個 attribute,對應到 static function,用於在 Unity Editor 的各個部分加上新的選單選項。
  • 依照添加的路徑,自訂的選項會顯示在不同地方:
    • 以 Assets 為開頭,會同時增加選項至上方工具列、project 視窗的右鍵選單。
    • 以 GameObject 為開頭,會同時增加選項至上方工具列、hierarchy 視窗的右鍵選單。
    • 以 CONTEXT 為開頭,會增加選項至 component 的右上齒輪選單。
  • priority 的設置:
    • 小的數字在上方。
    • 差距超過 11 的選項中間會出現分隔線。
  • Menu.GetChecked / SetChecked 可以實現選項前方的小勾勾。
  • MenuCommand 可以在 component 的右上選單的實作上取得更多資料 (來自何 component 之類的)。

[閱讀筆記] Unity のエディター拡張 #1

發表於 2017-07-17 | 分類於 game-develop , unity |

閱讀《Unity のエディター拡張》後所留下的簡單筆記,第一到五章。 這是日本 Unity 技術人員 安藤圭吾 針對 Unity Editor 所寫的一本電子書,可透過下方連結看到原文。

  • https://anchan828.github.io/editor-manual/web/index.html

第一章:簡介

  • 諸多 Editor 相關的 API 位於 UnityEditor 這個 namespace 下,是只能在 Unity Editor 中使用,無法用於專案輸出。
  • 如果使用了 UnityEditor 這個 namespace 下的 API,腳本放在名為 Editor 的指定名稱資料夾中,避免專案進行輸出時出現錯誤。
  • Editor 資料夾可以為複數個,也沒限定位置。
  • 另外也可利用 UNITY_EDITOR 這個 Symbol 來防止專案進行輸出時出現錯誤。
  • 另有指定名稱 Editor Default Resources 的資料夾,限制必須位於最上層。
  • Editor Default Resources 本來是用於置換預設資源的資料夾,但也可做為 Editor 的資源資料夾,用 EditorGUIUtility.Load 來讀取。
  • EditorGUIUtility.Load 必須使用以 “Assets/…” 為開頭,包含檔案副檔名的完整路徑,與 Resources.Load 需做區分。

第二章:用 Inspector 的內建 Attribute 修改編輯器

  • 參數部分
    • Range 針對單一數值給予範圍限制,編輯器多一條拉桿。
    • Multiline / TextArea 替換 string 的編輯器為多行版本。
    • ContextMenuItem 為參數增加右鍵選單。
    • ColorUsage 更改與限制 Color 參數的編輯器樣式。
  • 編輯器顯示部分
    • Header 加上一段粗體小標題。
    • Space 加上一段指定高度大小的空白。
    • Tooltip 游標停在參數上會顯示一段文字的浮動窗。
    • HideInInspector 隱藏對應參數在編輯器的顯示。
  • Component 部分
    • RequireComponent 要求該 Component 需依賴於其他特定 Component 才能使用,也可防止被依賴的 Component 被移除。
    • DisallowMultipleComponent 不允許一個物件上有多個相同的指定 Component。
  • 其他
    • FormerlySerializedAs 用於指定 Serialize 參數對應的資料名稱,即使變數名稱被修改也不會遺失原本的設定值。
    • AddComponentMenu 讓自訂的 Component 可在 AddComponent 的選單中顯示。
    • ExecuteInEditMode 使部分 Message 函式在 Non-Play 模式也會被運行。
    • ContextMenu 在 Component 的右鍵選單中增加選項。
    • SelectionBase 讓對應的物件在場景中更優先被選擇。

第三章:資料的保存

  • 共用於所有專案,關於 Unity Editor 的設定,會保存在電腦某個地方。
  • EditorPrefs.Get / SetXXX 可以用來讀取或寫入這份設定檔。
  • 專屬於專案的設定檔,會保存在 Library/EditorUserSettings.asset,而且有簡單加密。
  • EditorUserSettings.Set / GetConfigValue 可以用來讀取或寫入這份設定檔。
  • ScriptableObject 可以將一個類別與其成員的值,儲存為一個獨立 Asset 在專案之中。
  • 5.3版的新功能 JsonUtility,使用上有限制,且效能不好建議少用。

第四章:ScriptableObject

  • ScriptableObject 是一種可自訂的 Asset。
  • ScriptableObject 同時也在編輯器中無所不在,GameView、EditorWindows 都是其子類別。
  • 必須使用 ScriptableObject.CreateInstance 來實例化,才能註冊到 Unity 的管理機制中運作。
  • 相關 API
    • AssetDatabase.CreateAsset 將實例儲存為專案資源檔。
    • 儲存後需要用 AssetDatabase.ImportAsset 或 AssetDatabase.Refresh 註冊資源檔的資訊。
    • AssetDatabase.LoadAssetAtPath 從資源檔案讀取 ScriptableObject。
    • AssetDatabase.AddObjectToAsset 可以操作檔案間的 關聯 (Referance,可想成拖曳檔案至 Inspector 對應變數欄位中的這個動作)。
  • 建立親子關係的 ScriptableObject,在 Project 視窗也會呈現階層的結構,此時可以使用 hideFlags = HideFlags.HideInHierarchy 將子物件隱藏。
  • 在 Gizmos 資料夾中,以 [類別名稱] Icon 命名圖片,會自動作為對應 ScriptableObject 的 icon。

第五章:SerializedObject

  • SerializedObject 是 UnityEngine.Object 與資源檔案的中間橋梁,作為檔案時將資訊以 meta 檔儲存。
  • 關於 Serialized:https://docs.unity3d.com/Manual/script-Serialization.html
  • 在 Editor 中,Undo 與 Selection 皆是透過 SerializedObject 來實現。
  • 在 Editor 中,透過存取 SerializedObject 中的 SerializedProperty,來進行專案內容的編輯與控制。
    • (反過來說,不是 SerializeField 是無法透過 Editor 控制的)
  • 如果開啟了一個 Editor Windows,則對於專案的 UnityEngine.Object 會透過另一個獨立的 SerializedObject 控制,不同 Editor Windows 之間,或者自訂 Editor 與原生 Editor 之間的同步需要注意。
    • serializedObject.Update () 可以重新進行資料更新。
    • serializedObject.ApplyModifiedProperties () 可以對資料更動進行寫入。
    • SerializedObject.GetIterator () 用於處理陣列。

小筆記

  • 第五章感覺只算是簡單帶過,很多細節並沒有深入解釋,可能因為本書以 Editor 為主題,如何操作優先於解說實際底層。

[閱讀筆記] Unity shader 入門精要 #5

發表於 2017-06-04 | 分類於 game-develop , unity |

《Unity shader 入門精要》的讀書筆記,十六章到十九章。 十六章說明渲染上的優化方向;十七章簡單說明了 surface shader;十八章簡單說明了 PBS 技術。 十九、二十章說明一些 Unity 的更新,以及精進渲染技術知識的方向。

第十六章:Unity 的渲染優化

  • 一開始就把優化當作設計的一部份
  • 造成遊戲瓶頸的可能原因:
    • CPU - 過多的腳本運算或物理模擬
    • CPU - 過多的 draw call
    • GPU - 過多的頂點、逐頂點運算
    • GPU - 過多的 fragment、overdraw
    • 解析度過高的貼圖、frame buffer
  • 優化方向:
    • 減少 draw call
    • 優化模型、使用 LOD、Occlusion Culling
    • 控制繪圖順序
    • 注意透明物體的使用
    • 減少即時光照
    • 減少 overdraw
    • 壓縮貼圖大小
  • 使用動態 batching 減少 draw call:
    • 使用同一個材質,Unity 會自動實現動態 batching
    • 一次動態 batching 所能接受的頂點數上限為 900
    • 多 Pass 的 shader 無法動態 batching
  • 使用靜態 batching 減少 draw call:
    • 將物體設定的 static 打勾
    • 在程式運作一開始,將數個模型合併
    • 會占用更多記憶體
    • 物體不可被移動
  • 共用材質的技巧
    • 合併貼圖
    • 將相異的 shader 參數儲存於頂點顏色 (或其他頂點數據)
    • 使用 Render.sharedMaterial
  • 減少 overdraw 技巧:
    • 對於確定會在最前方的物體,調整其渲染順序往前
    • 減少透明的使用
    • 在移動裝置上,因為 GPU 架構的差異,透明度混和可能會優於透明度測試
    • 使用 lightmap 代替即時光照,移動設備上甚至要避免使用逐像素光照
  • shader 程式碼優化
    • 用 float 儲存頂點座標,用 half 儲存 uv 座標,用 fixed 儲存單位向量
    • 避免變數精度轉換
    • 盡量合併差值計算
    • 盡量避免 if、loop 語法
    • 盡量避免三角函數跟指數運算
    • 盡量避免 discard,這跟一些 GPU 的優化架構有關
    • 一些細節會因平台而異

第十七章: surface shader

  • surface shader 是 unity 對於 shader 的進一步抽象封裝
    • https://docs.unity3d.com/Manual/SL-SurfaceShaders.html
    • 在 SubShader 中編寫而非 Pass
    • 方便撰寫但能夠實現的自定義渲染較有限
    • 性能較差,但如果需要處理許多光照,是個好的選擇
    • 如果光照單純,使用 vertex/fragment shader 效能會好很多
  • 編譯指令 #pragma surface 用於定義使用的函數及光照模型
  • 函數格式:
    • void surf (Input IN, inout SurfaceOutput o)
    • void surf (Input IN, inout SurfaceOutputStanderd o)
    • void surf (Input IN, inout SurfaceOutputStanderdSpecular o)
    • Input 結構有一些內建的變數、也可自訂增加變數
  • 光照模型:
    • Standard 標準物理光照
    • StanderdSpecular 物理金屬光照
    • Lambert
    • BlinnPhong
    • 或者自行定義:https://docs.unity3d.com/Manual/SL-SurfaceShaderLighting.html
  • 其他參數:
    • vertex 修改頂點的函數
    • finalcolor 在顏色存入 frame buffer 前進行修改的函數
    • adddhadow、fullforwardshadows、noshadow
    • alpha、alphatest
    • exclude_path 可以在移除對特定的渲染路徑的支援

第十八章:Physically Based Shading,PBS

  • 基於物理的渲染 Physically Based Shading
    • 比起 Lambert,使用了考慮細微漫射及次表面散射的 BRDF 等式
    • Standard 跟 Standard Specular 使用相同的 BRDF 等式,只是對外調整的參數項目及意義不同,依然可以做出相同的表現
    • 使用 HDR 的 skybox 可以表現出更真實的光照,擁有更高的亮度精度,但是運算需求也較高
  • Unity 5 的 Global Illumination (GI) 可以提供間接光照,增加光照的真實感,可由光源的 Bounce Intensity 調整間接光照的強度
  • 平行光的 Baked 模式會將場景光照儲存到一張 lightmap,Mix 模式則只儲存 static 物件的光罩,剩餘物件採用即時渲染
  • 反射探針 (Reflection Probes) 的設置,可以提供反射所需的 cubemap
  • Gamma space 與 Linear space 的顏色差別:
    • Linear space 較接近真實的顏色
    • 一般紋理貼圖是以 Gamma space 儲存,如果硬體支援,Unity 會自動進行顏色空間的轉換
    • 如果硬體不支援,可以在 shader 中以效能為代價進行手動轉換
12

douduck08

27 文章
10 分類
24 標籤
GitHub FB Page
© 2019 douduck08