Unity C# 程式基礎
與遊戲控制邏輯入門
從組件架構、生命週期、變數、GetComponent、條件判斷到 Time.deltaTime,最後串成一個 2D 跑酷遊戲。
按 ← → 鍵或下方按鈕切換頁面
腳本就是「自訂組件」
GameObject 是空車架
本身沒有功能,必須安裝組件:引擎組件讓車能跑,喇叭組件讓車能響。
2D 圖片預設組件
- Transform:位置、旋轉、縮放
- Sprite Renderer:顏色、透明度、圖層順序
建立腳本
Project 面板右鍵 Create → C# Script,或在 Inspector 按 Add Component → New Script。名稱用 PascalCase,如 PlayerMovement。
檔名必須等於類別名
PlayerMovement.cs 裡寫成 class Playermovement(大小寫不同),Unity 就無法辨認,也無法掛載到物件。
三個核心生命週期函式
| 函式 | 執行時機 | 用途 |
|---|---|---|
Start() | 物件啟用時,只執行一次 | 初始化、GetComponent 綁定組件 |
Update() | 每一幀執行一次 | 偵測按鍵、計時器、非物理邏輯 |
FixedUpdate() | 固定時間間隔,不受幀率影響 | Rigidbody2D 的移動與受力 |
為什麼物理放 FixedUpdate
Update 的次數取決於硬體:144 FPS 與 30 FPS 的電腦,每秒執行次數差很多,直接移動剛體會讓速度不一致。
void 是什麼
代表函式執行完不回傳任何資料。回傳整數寫 int,回傳文字寫 string。
變數:先「報戶口」再使用
// 資料類型 變數名稱 = 初始值; public float speed = 5f; // 公開到 Inspector,可即時調參 public static float speed = 5f; // 其他腳本用 GroundMove.speed 直接存取
常見型態
- int:整數(分數、關卡)
- float:小數,數值後要加 f(5f)
- string:文字,用雙引號
- bool:true / false(isGrounded、isDead)
- GameObject[]:陣列,索引從 0 開始
實用小技巧
float 轉成 UI 文字時,用 distance.ToString("F0") 去掉小數位,只顯示整數公尺。
Tag 區分大小寫
Inspector 的 Tag 是 Ground,程式碼寫 "ground" 條件就會失效。
GetComponent:取得組件控制權
Rigidbody2D rb; // 1. 宣告 Animator anim; void Start() { // 2. 在 Start 或 Awake 綁定 rb = GetComponent<Rigidbody2D>(); anim = GetComponent<Animator>(); } // 3. 之後用 rb、anim 控制屬性
常用組件
- Rigidbody2D:
rb.linearVelocityX設定水平速度 - Animator:
anim.SetBool("run", true) - SpriteRenderer:
spr.flipX = true解決倒退跑 - AudioSource:
.Play()/.Stop()
Awake 與 Start
Awake 最早執行,適合組件自身的內部綁定(如 AudioManager 取得 AudioSource)。Start 在 Awake 之後,適合依賴其他物件的初始化,這樣其他腳本在 Start 播放音效時,AudioSource 已準備好。
if 判斷與玩家輸入
if (Input.GetKey(KeyCode.RightArrow)) movement = speed; else if (Input.GetKey(KeyCode.LeftArrow)) movement = -speed; else movement = 0f; // && 兩個條件必須同時成立:防止空中連跳 if (Input.GetKeyDown(KeyCode.Space) && isGrounded == true) rb.linearVelocity = new Vector2(movement, jump);
GetKey 與 GetKeyDown
GetKey:按住時每一幀都是 true。GetKeyDown:按下瞬間只回傳一次 true,適合跳躍、攻擊、確認。
餘數運算子 %
groundCount % 10 == 0 在第 10、20、30 個地面成立,可藉此用 speed *= 1.5f 逐步加速。
== 與 = 不同
== 是比較是否相等,= 是把右邊的值指派給左邊。
Time.deltaTime:讓速度與硬體無關
Time.deltaTime 是上一幀到這一幀所花的秒數。乘上它,就把「每幀移動」轉成「每秒移動」。
| 情境(速度 10 單位/秒) | 計算 | 每秒總距離 |
|---|---|---|
| 144 FPS | 10 × (1/144) × 144 幀 | 10 單位 |
| 30 FPS | 10 × (1/30) × 30 幀 | 10 單位 |
distance += GroundMove.speed * Time.deltaTime; // 精確反映實際跑了幾公尺
不乘的後果:每幀 +5,144 FPS 每秒 720 單位,30 FPS 只有 150 單位,遊戲速度被硬體綁定。
綜合應用:2D 跑酷遊戲架構
| 腳本 | 職責 |
|---|---|
PlayerMovement | Update 偵測輸入、翻轉圖片、受限跳躍;FixedUpdate 套用水平速度;OnTrigger 以 Ground 標籤設定父物件跟著平台移動,以 Deathline 標籤判定死亡 |
GroundMaker | InvokeRepeating 定時呼叫,Instantiate 隨機生成地形,每 10 個地面加速 |
GameManager | 按 Enter 開始、累加距離並更新 UI、死亡後顯示 Game Over,按任意鍵 SceneManager.LoadScene 重載 |
AudioManager | Awake 先取得 AudioSource,提供 PlayTitle / PlayBgm 給其他腳本呼叫 |
劃分權責
一個腳本專注一件事。
善用變數
public 即時調參,static 跨腳本共享。
平滑時間
物理放 FixedUpdate,距離乘 Time.deltaTime。