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

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

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

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

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

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

1514274974581

讓遊戲動起來 – 遊戲迴圈 (Game Loop)

如果你去網路上搜尋 “遊戲迴圈" 四個中文字,跑出來的內容可能是關於遊戲體驗、遊戲企劃設計之類的內容,但這不是我說的對象;改用英文 “Game loop" 才比較容易精確找到我所想指稱的內容,精確對應的中文專有名詞應該是沒有吧。

一個 Game loop 分成了三個階段:

  1. Input:偵測並收集所有外部輸入的資料,包括玩家操作、資源檔載入、網路封包等。
  2. Update:依照當前既有的資料、以及最新的 Input 進行邏輯運算、資料更新
  3. Rendering:依照最新的資料,更新畫面

只要遊戲程式一被順利開啟、持續地在運作,這三個階段就不斷的被依序重複執行,形成一個迴圈 (loop),一直到遊戲被關閉結束,這迴圈都不會停止,是遊戲能夠 “被遊玩" 的基本原理。

舉例來說明的話:

  1. Input:按下鍵盤上的方向鍵。
  2. Update:發現最新的輸入資料有方向鍵,朝該方向移動腳色的位置資料。
  3. Rendering:繪製出最新的畫面,讓腳色的位置跟過去有所差別。

如此一來,遊戲角色就開始在畫面中移動了!

在這之間還有個一般玩家都會知道的名詞:禎率 (FPS,Frame per second),直接翻譯的話就是 “每秒的畫面數",在遊戲中代表著畫面更新速度,同時也代表著每秒運作了多少次的 Game loop 。跟電影或動畫一樣,遊戲也依靠每秒替換幾張圖片來讓畫面動起來,只是遊戲作為 “可以控制的動畫" 多了 1 跟 2 兩個步驟。

Unity 在 Game loop 上的實現與窗口

使用 Unity 進行遊戲開發,遊戲的運作原理依舊離不開 Game loop 的概念,只是三個步驟被打散到遊戲引擎的不同功能,並由引擎本身來進行整合,實現遊戲的運作。

Input 部分

Unity 的程式腳本 API 中,便有一個以 Input 為名的類別,可以用來得知玩家的輸入訊號,包括鍵盤、滑鼠或是觸控螢幕的點擊。配合在專案中對 Input Manager 的設定,還能取得搖桿的輸入訊號;配合 GUI Event System 的設定,則可以直接對應到 UI 元件的輸入等。

這些 Input 訊號會由 Unity 統一擷取,被且將訊號的最新資訊儲存在遊戲引擎的某處,Update 階段再由腳本呼叫 API 進行取用。

另外檔案讀取的部分,Unity 有場景 (Scene)、資源 (Resource)、串流 (Steaming Asset) 等不同手段,用來配合不同的需求。網路部分則有 WWW 以及 UnityWebReqeust 兩個類別來支援;若有需要,.NET C# 提供了 TCP 與  UDP 的 Socket 連線類別,在 Unity 上也能直接使用。

Update 部分

如果要撰寫 Unity 的腳本,第一個會認識到的類別便是 MonoBehaviour,這是每個要跟 Unity Game Loop 進行互動時,必然要使用到的類別。

不同遊戲的 Update 階段會因為相異的玩法與設計需要,有著各式各樣的自訂邏輯,為了要將自訂的邏輯定義給 Unity 執行,一般會將相關的程式碼寫在 MonoBehaviour 的 Start、Update、FixedUpdate 等方法中,來與 Unity 進行互動。

可以想像成 Unity 的 Game loop 在 Update 階段留下了許許多多的空格,讓遊戲開發者將邏輯相關的程式碼直接填入其中。這樣當 Game loop 運作的過程中,Unity 會在符合定義情況時,直接取用對應區塊的程式碼來執行,就像在一個現成個骨架上推砌積木,讓開發者建立出形形色色的玩法。

對應不同的情況跟時機,Unity 會執行的方法 (Message Function) 有相當多種類,在開發 Unity 遊戲時,如果有數個物件之間會相互影響,便要注意這些 Message Function 的先後順序,來避免預期之外的錯誤發生。要記得,Unity 是個開發工具,不是通靈許願機,只有你主動去了解並正確的使用它,遊戲才能真正地依照設計去運作。

除了直接用腳本來告知 Unity Update 邏輯,還可以配合內建的許多工具:動畫狀態機 (Animator)、物理碰撞器 (Collider)、腳色尋徑 (Navigation) 等功能,來節省需要撰寫的程式碼,以及配合動畫控制、物理系統上的複雜開發。

Rendering 部分

在 Unity 中,任何 Update 階段對場景配置進行的更動,都會透過許多 Unity 的 API 來完成,而 Unity 再透過場景的配置 ,自動地完成畫面的繪製與更新。

原本作為畫面呈現的這個階段,越是複雜的遊戲,越是有著包山包海的開發工作要進行,但是 Unity 做為一個遊戲引擎,已經內建完成了大部分的工作,我們只要利用不同的 GameObject 跟 Camera 來排列出想要的畫面即可。

除了 GameObject 的位置,為了做出各種不同的畫面效果,Unity 提供了 Partivle System 以及 Shader Lab 來提供開發者進行特效製作與自訂的畫面效果。

一般來說,Rendering 的開發細節與原理會歸類在 Unity 的進階部分,不只是要能了解 Unity 本身的知識,還要進一步吸收關於 Rendering Pipeline 等遊戲開發的理論原理,才能自由自在地做出理想的畫面,可以說是無底洞般的大坑。

不過 Unity 的 Asset Store 跟網路上已經有了許多付費或免費的資源,透過社群交流與分享的力量,讓本來是神秘黑科技的遊戲開發細節,成為相對容易使用的現成工具,可以直接用在遊戲的開發上,這也是使用商業引擎開發遊戲的主要優勢之一。

 

對於新手入門的建議

做為一位從程式入門的 Unity 開發者,我會推薦想接觸 Unity 開發的人先從簡單的畫面、簡單的玩法來練習、了解 Unity 的原理

或許華麗的畫面與複雜的遊戲操作是你想達到的開發目標與初衷,但是 Unity 要開發出相對高級的遊戲,需要透入的知識與心力也是相對很高的。

另外關於程式到底要不要先學好?我也會推薦先學會寫程式,或者直接跟會寫程式的人合作。

即使因為 Unity 的各式功能,需要寫的程式碼數量看起來不會太多,但是 Unity 能夠幫助你的是關於玩家操作與畫面呈現,最後核心的遊戲邏輯你還是必須自己來撰寫,就算利用圖形化工具來避開程式碼,你還是需要有 用程式的角度去思考問題 的能力,才能創造屬於自己的玩法。

專業的遊戲開發團隊會細分成很多職位,如果不擅長或不想寫程式,想專精在練習遊戲美術或者特效的話,那找個夥伴逼他去學程式吧!

廣告

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s