發表文章

目前顯示的是有「Unity」標籤的文章

Unity:嘗試使用Zenject、Unity的Localization在地化插件與UIToolkit在一起

圖片
    前陣子接觸到Unity的新的UI工具UIToolkit,讓我想到以前碰到網頁排版和樣式要寫CSS的日子。很好奇目前重製版專案裡的UI是否也能順利轉換到UIToolkit上,由於我UI在功能上有用到Zenject所以想趁著這陣子有空來測試看看,能不能順利轉換。 之所以寫這篇文章是因為網路上查到有用 UIToolkit和Zenject在一起的人並不多,所以想拋磚引玉看看有沒有人也有類似經驗可分享。 測試對象:一個會使用到Zenject和Localization功能的按鈕 測試的項目很簡單,挑一個比較有代表性的元素做測試。 我選擇的是一個帶有文字敘述和圖片的按鈕,這個按鈕其實是展示畫作圖片的按鈕。UGUI版本中是一個Prefab,上面有個元件可以指定這個按鈕的圖片和文字敘述,文字敘述會由Localization這個插件負責載入在地化版本的文本,而這個按鈕的功能很簡單,按下去後會使用Zenject的Signal發出訊息,會滿版顯示這個按鈕的圖片和文字敘述,以下的影片為UGUI版本的展示: 由於我選擇的按鈕文字敘述和圖片是綁在一起的, 所以我就用ScriptableObject包起來,裡面裝有LocalizedString和Sprite。其中有個事件,用來通知在地化文本的語言變更,UI的部分接收到通知後再取得最新的在地化文本。 怎麼寫客製化的VisualElement 針對怎麼寫一個客製化的VisualElement在官方的文件有簡單的說明,可以先看此: Using custom (C#) elements 我這邊客製化的VisualElement稱作ImageBoxElement,以下的程式也會用這個名字示範。 客製化的VisualElement裡面的內容可以透過程式添加,類似這樣: ImageBoxElement.Add(new Label("NewLabel")); 或者是透過UIBuilder做出一個範本(類型是VisualTreeAsset),並透過在程式中載入的方式添加,有點像是在UGUI排好UI元素然後做成Prefab的概念。記住裡面會用程式控制的元素記得命名。 如下圖就是我製作的範本,稱作ImageBox: 載入並動態生成的方法,我是用Addressables載入: public class ImageBoxElemen...

Unity:餵魚小遊戲

圖片
    最近終於製作好了一個餵魚的小遊戲,是四景山水圖秋景-URP重製版這個專案裡的一部分,內容很簡單只有餵魚的互動功能而已,主要會做這個的動機還是添增趣味。 在傳統園林裏面水是很重要的,雖然這個專案目前看大概不會太著重在怎麼理水這方面,因為一些素材都沒有(石材駁岸和植栽的模型之類),所以也沒有辦法做太多處理,但是水的部分只有湖面就很無聊,所以加一點可互動的功能。之後肯定還會在水裡加上其他細節像是植栽之類的,讓水體這個部分變得豐富一些。   這個餵魚小遊戲分成兩個部分,魚的模型和渲染以及互動的部分 魚的模型和渲染 魚隻的渲染是利用Shader來處理魚的變形動畫和花色的變化。   魚的互動 互動包括游動、吃飼料和如何灑飼料。魚隻游動吃飼料都是依靠插件完成,插件使用的是 FlockBox ,基本上魚類游動與吃飼料可以簡單的做到,但是有個問題是與地形的碰撞,目前為止然有些障礙,有些魚會穿過地形。除此之外魚類游動的時候還會計算角度的差值傳給Shader做魚隻模型的變形。 灑飼料和水花這些都是依靠粒子系統搭配腳本控制,灑出來的飼料一開始是一般的粒子,等到碰到水面後才變成可以被魚隻辨別並吃掉的物件(在插件裡稱做Agent),飼料的物件用物件池管理,等要生成時才依照對應的參數召喚。    

專案:四景山水圖秋景-URP重製版與原先計畫的變動

圖片
  首圖是目前重製版製作中的截圖 最近的變化 最近部落格變得很少更新,主要是因為我試著把過去的論文作品更新,從Built In RP升級到URP渲染。同時因為舊的筆電狀況開始惡化讓我不得不準備提早將筆電退役換新電腦。差不多過年前就完成新電腦的組裝了,換的是桌機,所以結束了十三年都靠筆電開發的歲月,之後可能還會購入筆電,但是開發主力都在桌機了。 原有的計畫 原先的計畫是想要在Unity建造一座傳統園林,而且是符合現代生活氣息的。平面上基於論文作品中也使用的南宋劉松年《四景山水圖.秋景》中出現的平面(只有中心住宅院落是,以外自行設計)。動機上跟在Minecraft蓋一座自己的住宅來住是一樣的,無非就是在虛擬世界實現自己的理想。 原本是想要在設計好平面後再來買新電腦 ,不過問題就在過很多年了都沒有重啟設計。所以在這樣的狀況下又轉而向先行製作非常簡單的小場景作為前驅的試驗來累積經驗。 例如擷取幾個傳統園林的景來製作,多做幾個景來累積製作各項景觀元素的經驗、技術和資源。也有打算做個現代風格的合院場景來測試URP的性能與視覺效果。 下圖是很早期設計的平面圖,平面圖範圍只有設計到中心的雙層住宅建築院落,而我想做的是範圍廣大的園林,所以進度很少。 現有的計畫 後來是因為筆電狀況急速惡化換了新電腦,於是決定直接投入將論文的作品升級。從Built In RP升級到URP渲染,某種程度上就是重製。於是前面提到想擷取幾個傳統園林的景來製作的部分也併入重製的計畫裡面,雖然並不會放置在原畫有明確描繪的範圍內。這是為了維持這個論文作品最初的目的之一 - 忠實復原畫中場景。這些擷取的景會放在原本周遭沒有東西能看的空間中可以隨意瀏覽。 渲染的風格依照原有的論文作品使用的是寫實PBR, 因為早期技術限制有些地方很不真實或粗糙,所以重製也會一併補強。 在Unity建造一座具有現代生活氣息的傳統園林,這個最終目標依然不變,只不過依然還是得等到論文作品重製版完成後才能進行,順便藉由重製版來獲取相關經驗、技術與素材。渲染風格可能會是風格化PBR,目前還不確定。 論文作品重製版  目前重製版製作已經一個多月了。主要要達成的目標有幾個。 第一個就是介面要有雙語。因為原先只有中文,其他語系的國家即使看到想來探究也很困難。 第二個是材質和模型重製 。當初是第一次碰Unity,對很多3D渲染的技術和經...

Tree It:免費且功能豐富的捏樹軟體

圖片
    我前陣子在Reddit上面看到有人在Unity的討論區詢問捏樹的軟體,有人推薦了Tree It。我試著使用後發現這套軟體不但功能比Unity內建的捏樹功能豐富且強大。Unity內建的捏樹功能其實滿簡單的,而且有侷限性,並不是很好用。我還有看到一套Unity插件叫做Mtree,不過需要付費 Tree It 雖然不如SpeedTree強大,可是基本要用的功能應有盡有,而且免費。以下我會分享一些我覺得滿實用的功能與一些缺點,然後如果時間允許在下一篇文章我會分享如何將Tree It製作的樹匯入Unity中還帶有風力的頂點動畫。 支援節點的手動編輯 植栽的外型不僅可以靠參數設定生成,也可以手動編輯節點,因此可以控制枝條各個節點的位置、角度等等,甚至能夠截斷枝條,而葉片也可以手動選取刪除。   沒有自訂樹狀階層的功能 跟Unity內建的樹狀階層不同,TreeIt每個檔案階層數目與類別是固定且有限的,只有樹幹>>枝條>>小枝條>>葉片(Mesh)。 然而你可以把捏成的樹當作Mesh使用,捏好後的樹即使被當作Mesh使用風力也能正常計算,所以並不是太大的問題。在TreeIt本身附的範例中可以看到很多是單獨捏出分枝的枝葉的模型然後再將這片枝葉的模型當作Mesh使用,所以實際上階層數目和和種類依然可以自訂,只是與Unity的運作方式不太一樣。   將植栽直接渲染成貼圖 可以將捏好的植栽依照目前的視角渲染成貼圖,貼圖種類跟支援的貼圖一樣,包含顏色、法線、光滑度、透光度四種。 這個功能很好用,除了直接做Billboard之外還能將捏好的枝葉渲染成貼圖。  雖然圖中沒有顯示,但是這套軟體會自動處理邊緣的Dilate(Padding)。     手動調節面數 沒有自動生成LOD的功能,但是有刪減面數(Poly Reduction)的功能,枝葉也能調節段數。   更豐富的參數控制 控制枝葉的形狀、生成位置等等參數控制比Unity內建的捏樹功能更多能控制的細節。   貼圖集(Texture Altas) 可以把多個同種類的貼圖打包成一張,Unity內建的捏樹功能會自動化不能自己設定。   烘焙於頂點色的Ambient Occlusion(AO) 雖然此軟體找...

Unity:嘗試製作可相交的視差遮蔽貼圖 Shader (Trying to Create an Parallax Occlusion Mapping Shader with Pixel Depth Offset)

圖片
  警告,本文只是分享摸索的過程,並不是完善的技術文。 此文在計算深度位移有錯誤,後續有所更新,詳見 此文     視差貼圖(Parallax Mapping)是一種改進後的凹凸貼圖的技術,可以用極少的面數模擬複雜模型的表面凹凸,因為介紹視差貼圖這個技術的文章很多了此處就不詳細介紹,本文只大概說明使用視差貼圖要怎麼讓模型與一般的物件產生正確的陰影投射和相交的效果。  一般的視差貼圖的做法是依照切線空間的視線相量位移貼圖採樣的 UV 座標而產生立體感,物件本身的幾何形狀並未更改,因此各個像素的深度也是原有形狀的位置,因此相交時無論畫面上的物體因為視差貼圖產生凹凸的樣貌為何,相交還是依照原有的幾何形狀,而接收物件陰影投射亦有相同狀況。(如下圖) Unity 中的 HDRP 中內建的 Lit Shader 提供的像素深度位移(Pixel Depth Offset)的功能,可以讓各個像素的深度位置依照視差貼圖位移的量產生位移,進而讓視差貼圖凹凸的效果也能對應到物件的相交上。(如下圖) 需要提到的是 Unreal 引擎的 Shader 也有同個功能,但無論是 Unity 和 Unreal 引擎的做法我都無法取得夠詳細的資料,雖然 Unity 的 Lit Shader 可以找到原始碼,但是太複雜了,目前暫時還是沒有辦法理清做法。 (゚∀。) 為了產生正確的物件相交與陰影投射勢必要計算出正確的深度,那麼怎麼計算正確的深度呢?我的做法就是直接將像素的世界空間座標依照凹凸的位移量計算出位移後的世界座標,然後再計算剪裁空間的座標,然後就得出深度了。 需要說的是我採用的視差貼圖技術是視差遮蔽貼圖(Parallax Occlusion Mapping,POM) ,原先是在 Shader Graph 中用 Custom Function 節點製作的,結果如下方的影片。   參考了 Unity 的做法,使用的是高度圖而非深度圖,因此高度(深度)最低為0,最高為1,需要特別注意。 取得視差位移後的深度首先第一步是求出視差位移後的高度(深度)。這個很簡單,回傳位移後的 UV 時一並回傳目前的高度(深度),如下圖可以看到高度最低至最高由 0 到 1 灰階漸層。 一旦取得高度後便可以取得世界空間的...

Unity:URP的獲取光照節點

圖片
  最近想要在URP用Shader Graph的Unlit節點上使用自定義的光照,所以要取得場景的光照資訊,Unity官方是有提供獲取方向光以及多重光源的光照資訊的 方式 。 問題就來了,新版的URP似乎沒有辦法照上面官方文章裡提到的方式獲取陰影,這個問題是出在獲取陰影的功能實際上要定義特定的指示詞才能計算陰影,如果沒有定義會變成不計算陰影。 翻了網路上的文章已經有人對此問題做出詳細說明, 可見此 。要獲取光照的陰影就需要把原先計算陰影的程式碼複製過來,直接在自定義的節點裡執行計算,在文章裡其實已經有完成品了,不過只有主光源,那麼如果要處理多重光源(這邊指的是除了主光源以外的Additional Lights)怎麼辦呢?  其實Unity官方的文章已經有說明了獲取多重光源的光照資訊,有一點問題就是沒告訴你怎麼取得陰影,如果照舊版URP,應該是跟獲取主光源陰影一樣的方法,陰影的值應該封裝在燈光的struct裡,同樣的在新版的URP也無法作用。 所以如果要在新版的URP獲取多重光源的陰影的做法與取得主光源的陰影是相近的,差異在多重光源獲取陰影要在獲取光照資訊裡的迴圈執行。同樣的,需要將世界座標轉換到陰影空間的座標,取得陰影的相關參數,並在ShadowMap採樣陰影。計算各個光源的光照強度與顏色( attenuatedLightColor )會變成如下: half4 shadowCoord = mul(_AdditionalLightsWorldToShadow[i], float4(WorldPosition, 1.0f)); half4 shadowParams = GetAdditionalLightShadowParams(i); ShadowSamplingData shadowSamplingData = GetAdditionalLightShadowSamplingData(); float shadowAtten = SampleShadowmap(TEXTURE2D_ARGS(_AdditionalLightsShadowmapTexture, sampler_AdditionalLightsShadowmapTexture), shadowCoord, shadowSamplingData, shadowParams, tru...