Unity 遊戲開發實戰學習隨筆
第一部分
入門
最好的學習方法是從入門的地方開始,先擺好工具並理清思路,完整的設計和實現遊戲所需的知識、技能和培訓的話,即便是世界上最好的遊戲思路,對你來說也沒有價值。
入門部分主要學習Unity這一引擎的基礎知識及其介面,以及如何從頭開始提煉遊戲思路。
隨書光碟檔案目錄:
DVD-ROM Contents:
1. Chapters
2. Design Documents
3. Shader Test
4. Final Project Files
5. Resource Files
6. Appendices
Unity引擎概覽
Unity是一個強大的整合遊戲引擎和編輯器,它讓你可以迅速高效地建立物件、匯入外部資源,並且用程式碼把他們連線在一起。
熟悉介面
1、Project檢視:遊戲中的所有檔案(指令碼、物件、場景、任何檔案)都組織到一個Project資料夾中,每個Project資料夾都會包含一個Asset(遊戲資源)資料夾。Asset資料夾包含你所建立或是匯入幷包含在這個遊戲中的任何東西,包括網格(mesh)、貼圖、指令碼、攝像機、關卡等。
2、Hierarchy檢視:Project檢視列出了遊戲中所有可用的物件和檔案,Hierarchy檢視僅僅列出了那些真正會在當前場景中用到的物件。
3、Inspector檢視:顯示遊戲中每個物件所包含的詳細資訊。
4、工具欄:變換工具、變換Gizmo切換、播放控制元件、分層下拉列表、佈局下拉列表
5、Scene檢視:編輯器中最重要的檢視之一——它是遊戲世界或是關卡的一個視覺化表示。
6、Game檢視
7、Animation檢視
8、控制檯和狀態列
Unity的核心是以資源為中心的,而不是以程式碼為中心的。
第一款遊戲:從哪裡開始
基本設計理論
遊戲最基本的單元是機制(mechanic),它是一個規則或描述,規定了遊戲模式中一個特定的、單個的方面。想象一下你最喜歡的一款遊戲,並且把你作為一個玩家可以在這個遊戲世界裡進行的不同的事情列成一個列表,這個列表中的每一項都是該遊戲的一種機制。
可以把相似以及相關的機制組織成為一個更大的規則集合,這稱為系統。設計良好的、具有想象力的系統是任何有趣的遊戲的核心。核心陳述通常組織為一個“人物、任務、地點”的形式。
第二部分
用地形搭建舞臺
建立環境:匯入基本的定製資源
Assets資料夾包含內容:
- Audio(音訊)
- Characters(角色)
- GUI(圖形使用者介面)
- Editor(編輯器)
- Particles(粒子)
- Props(道具)
- Scenes(場景)
- Scripts(指令碼)
- Skybox(天空盒)
- Terrain(地形)
建立角色
遊戲有一個設計得完美無瑕的遊戲空間那當然好,但是大部分遊戲設定都需要某種型別的居民,以使複雜的假象可以變為真實的。
玩家角色(Player Character,通常也稱為PC)只是玩家用來和遊戲進行互動的化身(avatar)。
通常分為三類:第一人稱、第三人稱和隱含/不存在的。
Unity中PC主要是由使用指令碼定製的角色控制器(character controller)來定義的,而不是在引擎中預先定義或是硬編碼的。
第三部分
互動性是讓遊戲真正可玩的東西——它把一系列靜態的美術作品和圖片轉化為一個有生氣的、會對玩家的命令做出反應的系統。在Unity中,大部分互動性都是通過指令碼程式設計來實現的,指令碼就是和各個遊戲物件相連線的指令片段,它可以描述這些遊戲物件在一個給定情況下的行為。
Unity中的指令碼程式設計
如果說模型、貼圖之類的可以給遊戲環境一個物理描述和設定,那麼指令碼和程式碼塊會給遊戲及其內容以生命。指令碼定義遊戲所有部分的基本互動、行為和規則。
Unity的所有遊戲邏輯都是基於Mono的,Mono是一個開源的.NET平臺,可以用來建立跨平臺的應用程式。底層的.NET庫提供了你想要的常用功能。
任何熟悉遊戲引擎中的指令碼程式設計環境的人,在開始使用Unity的API(Application Programming Interface,應用程式程式設計介面)時都不會遇到麻煩。
變數命名約定:
- 大部分變數:駱駝拼寫法(CamelCase),deltaTime
- 關鍵字:永遠小寫
- 列舉:通常大寫
- 函式:駱駝拼寫法
- 類:駱駝拼寫法
“駱駝拼寫法”又分為兩種。第一個詞的首字母小寫,後面每個詞的首字母大寫,叫做“小駱駝拼寫法”(lowerCamelCase);第一個詞的首字母,以及後面每個詞的首字母都大寫,叫做“大駱駝拼寫法”(UpperCamelCase),又稱“帕斯卡拼寫法”(PascalCase)。
編寫角色和狀態控制指令碼
計劃和設計
弄清楚是第一人稱視角還是第三人稱視角,攝像機應該怎樣跟隨它?
Unity3D Player角色移動控制指令碼
在Unity3D中,有多種方式可以改變物體的座標,實現移動的目的,其本質是每幀修改物體的position。
1、通過Transform元件移動物體
Transform元件用於描述物體在空間中的狀態,它包括位置(position),旋轉(rotation)和縮放(scale)。 其實所有的移動都會導致position的改變,這裡所說的通過Transform元件來移動物體,指的是直接操作Transform來控制物體的位置(position)。
1.1 Transform.Translate
該方法可以將物體從當前位置,移動到指定位置,並且可以選擇參照的座標系。 當需要進行座標系轉換時,可以考慮使用該方法以省去轉換座標系的步驟。
public float m_speed = 5f;
//Translate移動控制函式
void MoveControlByTranslate()
{
if (Input.GetKey(KeyCode.W)|Input.GetKey(KeyCode.UpArrow)) //前
{
this.transform.Translate(Vector3.forward*m_speed*Time.deltaTime);
}
if (Input.GetKey(KeyCode.S) | Input.GetKey(KeyCode.DownArrow)) //後
{
this.transform.Translate(Vector3.forward *- m_speed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.A) | Input.GetKey(KeyCode.LeftArrow)) //左
{
this.transform.Translate(Vector3.right *-m_speed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.D) | Input.GetKey(KeyCode.RightArrow)) //右
{
this.transform.Translate(Vector3.right * m_speed * Time.deltaTime);
}
}
或者
//Translate移動控制函式
void MoveControlByTranslateGetAxis()
{
float horizontal = Input.GetAxis("Horizontal"); //A D 左右
float vertical = Input.GetAxis("Vertical"); //W S 上 下
transform.Translate(Vector3.forward * vertical * m_speed * Time.deltaTime);//W S 上 下
transform.Translate(Vector3.right * horizontal * m_speed * Time.deltaTime);//A D 左右
}
1.2 Vector3.Lerp, Vector3.Slerp, Vector3.MoveTowards
Vector3既可以表示三維空間中的一個點,也可以表示一個向量。這三個方法均為插值方法,Lerp為線性插值,Slerp為球形插值,MoveTowards在Lerp的基礎上增加了限制最大速度功能。 當需要從指定A點移動到B點時,可以考慮時候這些方法。
1.3 Vector3.SmoothDamp
該方法是可以平滑的從A逐漸移動到B點,並且可以控制速度,最常見的用法是相機跟隨目標。
1.4 Transform.position
有時重新賦值position能更快實現我們的目標。
2、通過Rigidbody元件移動物體
Rigidbody元件用於模擬物體的物理狀態,比如物體受重力影響,物體被碰撞後的擊飛等等。
注意:關於Rigidbody的呼叫均應放在FixedUpdate方法中,該方法會在每一次執行物理模擬前被呼叫。
2.1 Rigidbody.velocity
設定剛體速度可以讓物體運動並且忽略靜摩擦力,這會讓物體快速從靜止狀態進入運動狀態。
//Velocity移動控制函式
void MoveControlByVelocity()
{
float horizontal = Input.GetAxis("Horizontal"); //A D 左右
float vertical = Input.GetAxis("Vertical"); //W S 上 下
//這個必須分開判斷 因為一個物體的速度只有一個
if (Input.GetKey(KeyCode.W) | Input.GetKey(KeyCode.S))
{
m_rigidbody.velocity = Vector3.forward * vertical * m_speed;
}
if (Input.GetKey(KeyCode.A)|Input.GetKey(KeyCode.D))
{
m_rigidbody.velocity = Vector3.right * horizontal * m_speed;
}
}
2.2 Rigidbody.AddForce
給剛體新增一個方向的力,這種方式適合模擬物體在外力的作用下的運動狀態。
//AddForce移動控制函式
void MoveControlByAddForce()
{
float horizontal = Input.GetAxis("Horizontal"); //A D 左右
float vertical = Input.GetAxis("Vertical"); //W S 上 下
m_rigidbody.AddForce(Vector3.forward * vertical * m_speed);
m_rigidbody.AddForce(Vector3.right * horizontal * m_speed);
}
2.3 Rigidbody.MovePosition
剛體受到物理約束的情況下,移動到指定點。
3、通過CharacterController元件移動物體
CharacterController用於控制第一人稱或第三人稱角色的運動,使用這種方式可以模擬人的一些行為,比如限制角色爬坡的最大斜度,步伐的高度等。
3.1 CharacterController.SimpleMove
用於模擬簡單運動,並且自動應用重力,返回值表示角色當前是否著地。
//SimpleMove移動控制函式 角色控制器
void MoveControlBySimpleMove()
{
float horizontal = Input.GetAxis("Horizontal"); //A D 左右
float vertical = Input.GetAxis("Vertical"); //W S 上 下
m_character.SimpleMove(transform.forward * vertical * m_speed);
}
3.2 CharacterController.Move
模擬更復雜的運動,重力需要通過程式碼實現,返回值表示角色與周圍的碰撞資訊。
//Move移動控制函式 角色控制器
void MoveControlByMove()
{
float horizontal = Input.GetAxis("Horizontal"); //A D 左右
float vertical = Input.GetAxis("Vertical"); //W S 上 下
float moveY = 0; m_gravity=10f;
moveY-= m_gravity * Time.deltaTime;//重力
m_character.Move(new Vector3(horizontal, moveY, vertical) * m_speed * Time.deltaTime);
}
連線動畫
動畫是遊戲視覺結構的一個重要組成部分——它們有助於把生命和角色帶入一個不再靜態的物件集合中。除此之外,它們有助於為玩家提供重要的資訊:我是在奔跑還是在行走?跳躍還是下落?這個敵人是真的擊中我了,還是我躲開了?
Unity中的動畫
Unity的動畫API非常強大和全面,它還包含整合的動畫編輯器。通常當你想起動畫時,往往會想到帶有多根骨骼並精心調整加權的角色動作。
1、Animation類
2、設定玩家控制器的動畫
3、在Unity內部建立動畫:整合的動畫編輯器對於一些應用來說特別有用——例如,新增新的動畫剪輯到Unity內部建立的物件或是元件,設定遊戲內渲染的過場動畫,在一段給定的動畫上加入你想要在特定時間點上發生的事件。
一些基本概念
Unity中的動畫是由關健幀(key)控制的。它們定義了動畫曲線(curve)。關鍵幀基本上儲存了一個給定物件在某個特定時刻的狀態的快照——一個遊戲物件可能會在時間0時位於點(0, 0, 0)上,並且在時間5時移動到點(1, 1, 1)。這兩個位置狀態中的每一個都會儲存為一個關鍵幀。曲線定義為連續兩個或多個關鍵幀。曲線定義為連線兩個或多個關鍵幀,以便對給定物件的完整運動路徑進行插值。曲線越平滑,所得到的動畫也越平滑。
新增動畫事件
動畫編輯器還可以為動畫剪輯加入一個非常有用的功能——同步事件。對於那些需要和螢幕上發生的其他動作相關聯的複雜動畫來說,這是可以方便地獲得的一種非常有用的功能。
例如,假如有一個四隻腳的角色並且有一個複雜的迴圈步行動畫剪輯與之相連。你最近找到一段很好的聲音效果,並且想要在這個角色每次把腳踩下的時候播放它。要手動做到這點,必須找到每隻腳接觸到地面的精確時刻,並且試圖匹配播放聲音的時刻。但是,如果你的幀頻是變動的或是在某一秒鐘慢了下來,那會發生什麼?效果可能會完全不匹配,這看上去或是聽上去不會很好。
使用一個動畫事件把這個事件直接和動畫的幀相關聯,因而它總是同步的。在這個示例中,你可以直接開啟Animation視窗,在圖上找到腳碰到地面的地方,新增事件來呼叫聲音效果。隨後,無論這段動畫播放得多快或多慢,聲音效果總是會及時播放。