---
# System prepended metadata

title: Unity FPS Lesson 1
tags: [程式社社課]

---

# Unity FPS Lesson 1

###### tags: `程式社社課`

## 移動/腳色物理
快速複習一下~
[Lesson 2 Unity 操作介面 / 常用 Component](https://hackmd.io/XhJuvYfRSrOitOLQlWt3zg?view)
[Lesson 3 自訂義 Component & 粒子特效](https://hackmd.io/OI7C9MPZTvqALtVGfYtPbQ?view)

### input
滑鼠移動、點擊、鍵盤按鍵、搖桿、多指螢幕觸控，Unity 都有支援
本教學以 PC 端鼠鍵操作為主
```csharp=
//有 raw 手感較硬、準、0 直接到 1
Input.GetAxisRaw("Horizontal");
//無 raw 手感較平順、0 慢慢滑到 1
Input.GetAxis("Vertical");
//按"下去"觸發
Input.GetKeyDown(KeyCode.Space)
//手"離開"觸發
Input.GetKeyUp(KeyCode.X)
//按著一直觸發
Input.GetKey(KeyCode.Z)
```

### rigidbody
![](https://i.imgur.com/gVhLOVA.png)

* Mass：物件的重量
* Drag：物件**移動**時的阻力
* Angular Drag：物件**轉動**時的阻力
* Use Gravity：是否受重力影響
* Kinematic：讓物件只受重力（以及一些其他東西）影響時使用
* Interpolate：幫助物件平穩的移動，如果物件的物理運動有抖動或不平穩的時候可以嘗試更改
* Collision Detection：碰撞偵測的模式，設定成Continuous 會防止穿透靜態物件，Continuous Dynamic 會防止穿透設定成Continuous 及Continuous 的物件
* Freeze Position 及 Rotation：能夠凍結物件的位置及旋轉

### update vs fixed-update
* update
	* 比 fixed-update 常呼叫，但不穩定，隨 loading 浮動
	* 通常處理輸入 / 邏輯判斷 / 繪製 GUI
* fixed-update
	* 絕對穩定
	* 通常處理物理 / 任何要求精準時間的動作/計算

## 視角
![](https://j.gifs.com/ywoWXE.gif)

### Quaternion (四元數)
我ㄉ念法：垮(qua) ㄊㄝˉ(te) 你恩(nion)
[我也看不懂的維基百科](https://zh.wikipedia.org/zh-tw/%E5%9B%9B%E5%85%83%E6%95%B0%E4%B8%8E%E7%A9%BA%E9%97%B4%E6%97%8B%E8%BD%AC)
~~你有可能也看不懂~~

用 Quaternion 可以躲掉萬向鎖的問題。

只要知道：
要改變一個物體的旋轉角度，使用乘，而不是加。
一次只改一個軸向，也不要直接修改他的 wxyz，除非你很確定你在做什麼。

## 射擊
![](https://j.gifs.com/J8ykYP.gif)
> 鎖爛 跟鬼一樣

### 子彈 Life cycle 優化處理
本次重點：**"Object Pooling"**
[參考 code](https://github.com/jasonkao402/FPS-tutorial/blob/main/Assets/Scripts/ObjPool.cs)

重點概念：
* 循環利用
	* 減少呼叫高延遲函數的次數，如 Instantiate 和 Destroy
	* 用到 queue 的尾巴時，會因為"取頭、放尾"的實作，重新使用到最早使用的 object。
* 預處理
	* 一開始就把要用到的數量提前準備好，也減少呼叫高延遲函數的次數
	* 就算要開更多物件來使用，也採取批量生成的方式處理
* 使用物件 ID
	* 取代 gameObject reference，盡可能還原 Instantiate 的用法
	* (因為會用到 Object Pooling 的都是會**大量使用**且**高度重複**的東西)

### 開鏡瞄準 (ADS)
右鍵按下開鏡，縮小視野**範圍** (放大視野內的物體)
右鍵放開解除瞄準，放大視野範圍。

## 槍枝資料
不同的槍會有不同的屬性，這些數字上的差異，也賦予每把槍各自獨特的手感。
如傷害、子彈初速、連發射速、裝彈量、reload time、垂直/水平後座力，等......
這裡我們使用「腳本化物件(ScriptableObject)」實作。

* 腳本化物件
	* Save / Load
	* 方便對大量物件進行動態更新
	* 類似一個資料庫的存在