# 遊戲引擎

一個人喺 Blender Game Engine 入面創建一隻賽車遊戲。Unity 個嘜頭；Unity 係廿一世紀初好受歡迎嘅一款遊戲引擎。
**遊戲引擎**（粵音：jau4 hei3 jan5 king4；英文：**game engine**）泛指設計嚟俾人開發電子遊戲嘅整合開發環境。一款遊戲引擎會有齊嗮啲俾人用嚟開發遊戲用嘅配套，而廿一世紀初嘅典型遊戲引擎會有呢四個基本組成部份：

* 聲引擎，包含啲好多遊戲都用嘅聲效，例如係爆炸嘅聲喺好多動作遊戲都會用到；
* 彩現引擎，包含一啲能夠做彩現，由立體模型嗰度製作出圖像嘅演算法（詳情可以睇電腦圖像）；
* 物理引擎，指處理遊戲物理嘅程式，會幫遊戲製作者模擬重力等多數遊戲嘅虛擬世界都要有嘅嘢；
* 遊戲人工智能，包括多數遊戲都用嘅人工智能程式，例如係基本嘅搵路演算法噉；

除此之外，遊戲引擎一般仲會有個圖像用家介面（GUI），而且多人用嘅遊戲引擎仲會有網上舖頭俾用家交流遊戲資產（指一隻電子遊戲當中可以獨立抽出嚟嘅一個有用部份，例如一個角色嘅立體模型、一首音樂或者係一段有用嘅程式碼呀噉）。廿一世紀初常用嘅遊戲引擎有 Unity 同 Unreal Engine 呀噉。

遊戲引擎嘅存在令遊戲製作呢家嘢平民化：一有咗遊戲引擎，就算冇受過電子遊戲製作相關訓練嘅人都可以攞住遊戲引擎嘅資源（聲效、程式同由網上舖頭買到嘅第啲遊戲資產）砌自己嘅遊戲出嚟，唔使吓吓都靠自己搵同編寫（例如）碰撞探測呢啲隻隻遊戲都要用嘅基本程式；因為噉，遊戲引擎被指係獨立遊戲喺 2010 年代得以崛起嘅主因之一。

## 基礎概念

一個用家喺度編輯緊一個立體模型；左上角嘅空間顯示個立體模型，而右上角嗰個空間入面嘅係遊戲嘅程式碼。
### 背景

遊戲引擎係俾人用嚟開發遊戲嘅整合開發環境（ 泛指俾人用嚟開發軟件嘅電腦軟件）：電子遊戲定義上就係以電腦軟件嘅型式存在嘅遊戲；一隻電子遊戲會有多個組成部份，包括咗

* 聲效（ 仲有指定「乜嘢時候要出邊個聲效」嘅電腦碼）、
* 一套處理圖像嘅系統（包括隻遊戲用嘅立體模型同彩現方法）、
* 遊戲物理（ 例如係一段指定遊戲世界嘅物件跟牛頓力學法則移動嘅碼）同
* 人工智能（AI；通常係用嚟控制啲 NPC）

... 等等。一般嚟講，有某啲嘅組成部份係好多遊戲都會想用嘅，例如係爆炸嘅聲效噉，多數動作遊戲同戰略遊戲都會用得到，或者一樖樹嘅立體模型，可以喺好多唔同遊戲裏面用嚟製作遊戲嘅虛擬世界。因為噉，電子遊戲業界嘅人就有咗個諗頭，想為遊戲開發者**一站式噉提供呢啲開發遊戲所需嘅資源**。

### 重要特徵

為咗達到呢個目的，一個由專業軟件工程師設計嘅遊戲引擎最基本上會做到兩樣嘢：

1. 包含一啲多數遊戲都要用嘅資源（遊戲資產 ），並且
2. 將呢啲資源擺喺一個簡單易用嘅用家介面下俾用家製作佢哋嘅遊戲。

例如廿一世紀初常用嘅遊戲引擎 Unity 同 Unreal Engine 會為用家提供呢啲資源之餘，仲會俾用家以「用踎士點擊同將物件拖入去遊戲世界」嘅方法製作遊戲世界－而唔係要用家齋靠編輯（對一般人嚟講相當難明嘅）遊戲程式源碼嚟製作遊戲。

順帶一提，一個遊戲引擎通常會有返咁上下可延伸度：可延伸度喺軟件工程上係指一隻軟件做到能夠喺出咗街之後容易加入新功能，而且加新功能嗰陣唔會搞到程式出錯；遊戲引擎本質上要應對係噉創新嘅遊戲設計，所以要能夠容易俾用家加入佢哋想要用嘅遊戲資產，而隻遊戲引擎嘅開發又需要能夠容易加入全新嘅功能。

### 遊戲程式

遊戲引擎做嘅嘢係建構一個個遊戲程式。一個遊戲程式嘅架構最基本上可以想像成以下噉嘅虛擬碼：

```
 **while**(isRunning) *// 當隻遊戲行緊，就一路做...*
 {
    Input->readInput(); *// 睇玩家俾嘅輸入...*
    isRunning = GameLogic->doLogic(); *// 行遊戲邏輯...*

    *// Update 遊戲世界嘅狀態...*
    Camera->update();
    World->update();
    GUI->update();
    AI->update();
    Audio->play(); *// 播要播嘅聲效。*
    Render->draw(); *// 按上述嘅資訊，畫出玩家應該要睇到嘅畫面。*
 }
```

用日常用語講即係話，一個遊戲程式做嘅嘢係一路係噉觀察玩家（用遊戲控制器等嘅架生）俾嘅輸入，按照輸入同遊戲世界嘅法則，決定遊戲世界跟住要點變化，然後更新遊戲世界嘅狀態同埋將更新咗嘅狀態顯示俾玩家睇。更新遊戲世界嘅途中會用到多個子系統，每個子系統負責其中一樣工作－遊戲引擎分起子引擎上嚟通常就係按呢種分法嘅，例如聲引擎對應 `Audio->play()` 同彩現引擎對應 `Render->draw()` 呀噉。

## 聲引擎

MIDI 格式嘅檔案會記住每個聲事件出現喺邊個時間點，可以想像成個檔案記住咗每一吓彈琴出現喺乜嘢時間。
聲引擎係指一個遊戲引擎當中負責處理聲相關工作嗰一部份。聲係電子遊戲當中嘅重要一環：電子遊戲嘅聲主要包括咗聲效同音樂；聲效通常係指一啲喺某啲特定事件發生嗰陣播一吓嘅聲，例如玩家角色開槍嗰時隻遊戲要播一吓槍聲，玩家角色掟出去嗰個手榴彈爆嗰時隻遊戲就要播一吓爆炸嘅聲... 如此類推，先至可以令個虛擬世界有返咁上下真實感；而背景音樂對於營造氣氛嚟講不可或缺－玩家角色去到安全地帶嗰時隻遊戲往往會播柔和嘅音樂，而當玩家角色進入戰鬥嗰時隻遊戲就往往會播一啲激昂嘅音樂，帶動玩家嘅情緒。

重要功能
一般嚟講，一個聲引擎需要做到以下嘅工作：

* 以某啲檔案格式儲住啲聲檔案，呢啲檔案會係遊戲資產；
* 俾遊戲製作者決定遊戲程式喺乜嘢時候播邊段聲，例：俾製作者指定遊戲世界發生爆炸嗰時要播爆炸聲；
* 俾遊戲製作者決定播聲嗰陣聲嘅源頭喺邊，例：俾製作者指定爆炸聲嘅源頭喺正爆炸發生嗰點；
* 俾用家喺個遊戲引擎裏面一定程度上噉編輯啲聲檔案，例如係混音嘅功能，俾玩家編輯一個聲唔同部份嘅響度同頻率等特性；
* 按遊戲物理，計算要播嗰段聲需要有乜嘢變化，例：如果玩家角色企喺離爆炸地點遠嘅地方，噉佢聽到嘅爆炸聲應該會細聲過企正喺爆炸地隔離聽到嘅－呢個過程當中會用到多普勒效應等描述物理現象嘅數學模型。响呢方面，唔同嘅遊戲引擎做法都有少少唔同，例如 2020 年嘅 Unity 就唔曉按遊戲世界嘅幾何特性嚟造回音嘅效果，不過會俾製作者落音頻過濾。
* 將適當嘅訊號傳遞俾部電腦嘅音響喇叭，等音響喇叭實際播啲聲出嚟；

... 等等。

多普勒效應嘅圖解；紅色嘅圓圈代表聲波，由上圖可以睇得出，隨住架車（聲波嘅源頭）郁動，會令到啲聲波由左邊聽起嚟頻率高咗，又會令啲聲波由右邊聽起嚟頻率低咗。一個聲引擎要識得模擬好似多普勒效應噉嘅聲學現象。
## 彩現引擎

彩現引擎包含啲能夠做彩現，由立體模型製作出圖像嘅演算法：同第啲動物（例如狗）比起嚟，人類係一個好依賴視覺嘅物種，傾向將自己對外界嘅判斷建基於視覺性質嘅資訊；因為噉，廿一世紀初嘅電子遊戲產業一般都認為，電子遊戲係應該要以影像做主導，即係用圖像嚟呈現隻遊戲嘅虛擬世界俾玩家感受，而且有親乜嘢回輸都以影像嘅方式俾（例：玩家成功打低一個敵人嗰陣，佢會見到個敵人跌低唔郁）。事實係實證研究表明，高質素嘅圖像能夠有效噉令玩家玩得更加投入更加過癮。

* 一個景入面有個鏡頭位置同埋若干件立體物件（ WIKINIUM\_MATH\_PH\_0 同 WIKINIUM\_MATH\_PH\_2 等，當中得 WIKINIUM\_MATH\_PH\_4 喺個鏡頭嘅視體入面），
最後要出嗰幅圖像係鏡頭見到嘅二維影像。

做完彩現出嘅一幅圖像
彩現係電腦圖像上一個重要嘅概念：到咗廿一世紀，電子遊戲主流都係用緊三維圖像；彩現係指運用電腦程式由一柞立體模型嗰度整一幅二維圖像出嚟嘅過程。想做彩現嘅人會首先整返個景檔案出嚟，呢個檔案會包含咗多種資訊，包括咗「個景入面用咗啲邊幾個立體模型」、「每個立體模型喺邊個位」、「個光源喺邊」同埋「個鏡頭擺喺邊個位置」呀噉，描述個景係點嘅；跟住部電腦會將呢個檔案入面嘅數據傳去一個彩現程式嗰度，等個程式做一大柞人手做唔嚟嘅運算，計出個鏡頭會睇到嘅二維影像應該係點嘅樣嘅，並且將個鏡頭所睇到嘅影像俾出嚟做輸出。

重要功能
一個遊戲彩現引擎要識得處理以下嘅嘢（睇埋三維電腦圖像）：

* 用某啲檔案格式儲住立體模型同天盒（如果隻遊戲用三維圖像）以及精靈圖（如果隻遊戲用二維圖像）等嘅遊戲資產；
* 俾用家揀啲資產點樣擺入去啲景入面，通常會係俾玩家喺個選單嗰度揀想要嘅遊戲資產，再用踎士左掣拉嚿嘢入去個景入面，跟手仲有得喺個視窗嗰度輸入想嚿嘢嘅坐標值係乜；
* 有多種嘅圖像管道（ 指定彩現嘅步驟嘅理論模型）俾用家揀，用家可以自由噉睇吓邊款最啱自己隻遊戲用，例如 2020 年嘅 Unity 就俾用家透過圖像用家介面或者 C♯ 碼嚟設定用邊種圖像管道，甚至乎俾用家創造自己嘅圖像管道；
* 俾用家控制鏡頭要擺邊同點郁，有啲遊戲（通常係動作遊戲）興將遊戲鏡頭擺喺玩家角色嘅頭裏面或者身後面，又有啲遊戲（通常係戰略遊戲）興將遊戲鏡頭擺喺個景嘅上空，等玩家有得鳥瞰式噉望遊戲世界嘅空間；進階啲嘅功能仲包括俾用家喺一個景入面設多過一個鏡頭，並且俾用家指定「乜嘢時候用邊個鏡頭」，又有功能會俾用家調較啲虛擬鏡頭嘅焦距同視體相關參數；
* 俾用家揀邊啲物件可以（例如）唔使做遮擋剔除或者唔使咁高解像度，甚至俾用家指定邊幾件物件淨係喺某啲時候可以唔做呢啲嘢－「喺冇必要嘅時候唔使整到件物件咁靚咁迫真」可以令隻遊戲行起上嚟對部電腦造成冇咁大負荷，所以可以令隻遊戲行得順暢啲；
* 模擬好多光學上嘅現象，例如係光源、陰影同反射呀噉。遊戲引擎正路仲會俾用家指定一嚿物體嘅「材料」－喺現實世界，唔同材料嘅嘢反射起光線上嚟嘅特性都會唔同，而遊戲嘅彩現引擎要模擬埋呢樣嘢，先至有可能做到迫真嘅影像。

... 等等。

## 物理引擎

四個遊戲物理嘅例子：

1 冇任何物理法則。

2 有重力，但冇碰撞探測。

3 有重力同碰撞探測，但冇剛體動力學。

4 有齊所有基本嘢。
物理引擎泛指用嚟模擬物理現象嘅電腦軟件，喺遊戲製作當中基本上實會用：除咗互動式小說等少數嘅遊戲類型之外，電子遊戲多數都會有個虛擬空間俾玩家控制某啲嘢喺入面郁動，所以一隻遊戲嘅世界多數要有物理定律主宰啲嘢應該點郁，而喺「更新遊戲世界狀態」嘅過程當中，個遊戲程式要按隻遊戲嘅物理法則同玩家輸入計返個世界嘅狀態應該點變，例如一隻用牛頓力學嘅賽車遊戲，喺玩家撳咗「踩油」嘅掣嗰陣，要改變架車嘅加速度數值，而架車相應嘅速度同位置等變數（喺遊戲引擎嘅程式當中通常係用向量嚟表示嘅）亦要跟牛頓力學裏面嘅法則作出相應嘅改變。除此之外，聲引擎同彩現引擎亦會用到聲學同光學等物理學領域上嘅理論模型。

舉個例說明，模擬牛頓第二定律之下郁動嘅物體可以想像成以下噉嘅 C 程式語言源碼：

```
double t = 0.0;
float dt = 1.0f;

float cuk\_dou = 0.0f;
float wai\_zi = 0.0f;
float lik = 10.0f;
float zat = 1.0f;
// 設一大柞變數，包括咗時間點（t）、時間間隔（dt）、速度（cuk\_dou）、位置（wai\_zi）、件物體受嘅力（lik）、同件物體嘅質量（zat）。

while ( t <= 10.0 ) // 重複噉計若干次，計到時間點係 10 為止。
{
 wai\_zi = wai\_zi + cuk\_dou \* dt;
 cuk\_dou = cuk\_dou + ( lik / zat ) \* dt; // 用牛頓第二定律計吓件物體受嘅力同佢嘅質量會點影響佢嘅速度。
 t += dt;
}

```

重要功能
一個遊戲引擎一般會模擬以下嘅物理現象：

* 牛頓力學（基本噉模擬位置、速度、加速度、重力同動量等嘅嘢）；
* 碰撞探測（喺每個時間點探測遊戲嘅虛擬世界有冇物體相撞）；
* 剛體動力學（模擬一啲由多嚿相連嘅物體組成嘅系統嘅郁動，例如物體嘅旋轉）；
* 布公仔物理（控制啲遊戲角色倒地嗰陣佢哋啲立體模型要點郁）；
* 為咗聲同彩現而模擬嘅聲學同光學現象；

... 等等。

## 遊戲人工智能

1982 年嘅食鬼遊戲；啲鬼有人工智能，曉追擊玩家。
電子遊戲會用到人工智能（AI）嘅技術：好多遊戲嘅關卡入面都會有敵人俾玩家打，啲敵人要曉唔只淨係企喺度，仲要識探測玩家嘅位置，並且攻擊玩家，以及對玩家嘅攻擊作出迴避等等，為玩家提供一定程度嘅挑戰－即係話要令遊戲角色作出有智能嘅行為，而「令機械展示智能」正正就係人工智能嘅定義。

一般嘅電子遊戲人工智能有以下嘅部份：

* **刺激詮釋器**：刺激詮釋器會話俾一個人工智能程式知個遊戲狀態係點；一般嚟講，每個個體敵人都會有個獨立嘅人工智能（除非隻遊戲係講玩家角色打緊一班具有集合心靈嘅外星人），每個智能會透過刺激詮釋器得到佢哋應該得到嘅資訊，跟住個程式要有方法表示「foreach 敵人，嗰個敵人手上有乜資訊」。
* **決策系統**：每一個人工智能都要按手上嘅資訊同自己嘅目的，計出跟住要採取乜嘢行動；例如一個敵人見到玩家，知道玩家嘅位置，而佢目的係要行埋玩家度攻擊佢，佢個人工智能程式就要有個方法教佢點樣用「玩家嘅位置」同「自己嘅位置」（個決策系統嘅輸入）計出「自己應該向乜方向移動」（個決策系統嘅輸出）。

## 編程功能

主流嘅廿一世紀遊戲引擎都會有**手稿**嘅功能：喺呢啲遊戲引擎當中，手稿係一啲程式碼，可以俾用家「貼」落去佢指定嘅遊戲物件嗰度，令件物件展現出佢想要嘅行為，而唔同嘅遊戲引擎都會有唔同嘅手稿語言（ 指嗰款遊戲引擎支援用嚟寫手稿嘅程式語言）；舉個例說明，2020 年嘅 Unity 遊戲引擎用嘅標準手稿語言係 C♯，用家可以用 C♯ 寫好一份份嘅手稿，然後再揀一份手稿，將份手稿「貼」落去其中個景嘅其中一件遊戲物件嗰度，令嗰件物件展現出手稿所指定嘅行為，可能嘅行為有「對某啲類嘅事件（例如一個敵人生命值變咗 0）俾噉樣噉樣嘅反應（將嗰個敵人剷走）」。呢種功能令到玩家有得創造自己專屬嘅遊戲物件，係用遊戲引擎搞遊戲製作走唔甩嘅一部份。

Godot 遊戲引擎當中嘅手稿編程用家介面；個畫面顯示一段段源碼。
例如係以下呢段 2020 年 Unity 嘅簡單手稿 C♯ 碼噉，就會令嚿物件喺佢身處嗰個景起始嗰陣產生一嚿由用家指定嘅物件：

```
using UnityEngine;
public class InstantiationExample : MonoBehaviour
{
 // 初始化，設定 myPrefab 呢嚿嘢做一個公開變數（用家可以喺 Unity 介面手動噉設定 myPrefab 嘅數值）。
 public GameObject myPrefab;

 // 以下呢段碼會個景開始嗰陣行一次。
 void Start()
 {
 // 喺 (0, 0, 0) 嘅位置產生一嚿 myPrefab，唔使旋轉。
 Instantiate(myPrefab, new Vector3(0, 0, 0), Quaternion.identity);
 }
 // 以下嘅碼喺每一個 frame 嗰度會行一次。
 void Update () {

 }
}

```

## 圖像用家介面

一個遊戲引擎嘅圖像用家介面有幾個大視窗，左上視窗顯示個景、右上視窗顯示其中一件物件嘅程式碼... 等等。
一個遊戲引擎要將上述嘅嘢擺喺一個圖像用家介面當中：原則上，聲、彩現、遊戲物理同埋人工智能冚唪唥都係可以齋用電腦碼嚟處理嘅（詳情可以睇遊戲編程）；不過電腦碼對一般人嚟講唔係咁易明，而遊戲引擎為咗要做到大眾化，會將各引擎嘅內容以一啲圖像－而唔係齋靠電腦碼－嘅型式顯示出嚟，呢種用圖像表示嘅方式就係所謂嘅 GUI ，例如有若干個視窗，一個視窗顯示現有嘅遊戲資產、下一個視窗顯示個景、下一個視窗用文字型式列出個景有嘅物件同每件物件嘅名... 等等，而且每個視窗都會對用家俾嘅輸入起反應，例如喺用家用指標點擊咗景現有物件視窗所列嘅其中一件物件嗰陣，個引擎彈個新視窗出嚟，顯示嗰件物件嘅詳細資訊。即係類似以下噉嘅碼：

```
 while True: *// 一路係噉做...*
   event = get_next_event() *// 睇吓發生咗乜嘢事（例：用家係咪撳咗踎士左掣同埋指標喺邊個位置）*

   *// 做相應嗰個子程序*
   a_function_to_handle_the_event = event-handlers[event]
   if a_function_to_handle_the_event:
     a_function_to_handle_the_event()

   if window_needs_to_close: *// 如果個視窗要關閉（例如用家撳咗踎士左掣，而指標喺個視窗嘅關閉掣嗰度），離開迴圈。*
     break  # out of the event-loop
```

## 出名引擎

* Unreal Engine
* GameMaker
* CryEngine
* Unity
* Godot

## 註釋

## 睇埋

* 第一身射擊遊戲引擎
* 遊戲開發
* 獨立遊戲
* 遊戲設計
* 電腦圖像
* 電腦模擬
* 線性代數
* 四元數
* 軟件工程
* 遊戲類型
* 遊戲引擎詞彙

## 文獻

* Anderson, E. F., Engel, S., Comninos, P., & McLoughlin, L. (2008, November). The case for research in game engine architecture (PDF). In *Proceedings of the 2008 Conference on Future Play: Research, Play, Share* (pp. 228-231).
* Bishop, L., Eberly, D., Whitted, T., Finch, M., & Shantz, M. (1998). Designing a PC game engine (PDF). *IEEE Computer Graphics and Applications*, 18(1), 46-53.
* Gregory, J. (2018). *Game engine architecture*. crc Press.
* Nandy, A., & Chanda, D. (2016). *Beginning Platino Game Engine* (PDF). Apress.

## 引咗

呢篇文用咗嘅行話詞彙，英文版本如下：

呢篇文引用咗以下呢啲文獻同網頁：

## 拎

* （英文） Unity 用家手冊
* （英文） Unreal Engine 用家手冊