Unity 2D 跑酷遊戲
開發全景指南
從環境建置、AI 生成素材、物理與動畫,到無限地形與專案打包——用一款《Pixel Dash》走完整條製作流程。
成品
AI 開場動畫、Suno 配樂、跑跳物理、越跑越快的無限地形、計分與 .exe 打包工具鏈
Unity · VS Code · Midjourney · Kling · Photopea · Suno開發環境:先把工具鏈接好
Unity Hub註冊帳號、Email 驗證後登入
▶
安裝編輯器Installed 頁籤選最新 LTS 長期支援版
▶
VS Code安裝 Unity 擴充模組,取得 IntelliSense 與除錯
▶
串接Edit → Preferences → External Tools 指定 VS Code
| 工具 | 分工 |
|---|---|
| Unity 編輯器 | 2D 場景、物理運算、動畫狀態機、UI、資源打包 |
| VS Code + Unity 擴充 | 撰寫角色控制、地形生成、遊戲流程的 C# 腳本 |
生成式 AI 素材工作流
圖像素材
- Ideogram / Freepik (Flux):天空背景、浮空島嶼
- Midjourney:Vary 生成同風格地形,
--sref統一風格,角色用 1:1 - AIEASE:物件消除與去背,輸出透明 PNG
- Photopea:裁切、複製拼接出寬窄島嶼、水平翻轉角色
6 格跑步關鍵幀 SOP
- 角色墊白底 → Kling AI 生成 6 秒跑步影片(風格最忠於像素原圖)
- MP4 拖入 Photopea 轉成圖層,縮為 300×300,取樣選最接近像素
- 挑 6 個動作幀,魔術棒去白底,微調前傾角度
- 逐幀匯出透明 PNG
為什麼不直接生成透明背景影片?品質較差——先補白底生成,再去背,結果更穩定。
2D 場景、物理組件與基礎移動
Order in Layer(越大越靠前)
- 天空 Sky:-2
- 地面 Ground:-1
- 角色 Player:0
剛體與碰撞器
- Rigidbody 2D 提供重力與速度;角色勾選 Freeze Rotation Z 防翻滾
- 雙方都要有 Collider 2D,至少一方有剛體
- 地面只掛 Box Collider 2D,邊線下調貼緊草皮
void Update() { // Update 偵測輸入;FixedUpdate 處理物理速度 if (Input.GetKeyDown(KeyCode.Space)) rb.linearVelocity = new Vector2(movement, jump); } void FixedUpdate() { rb.linearVelocityX = movement; } // Unity 2022 LTS 以前請改用 rb.velocity
地面偵測與動畫狀態機
GroundChecker 子物件
- 地面 Tag 設為
Ground - 腳部放空物件 + Box Collider 2D,勾選 Is Trigger
- OnTriggerEnter2D →
isGrounded = true;Exit →false - 跳躍條件:
Space && isGrounded,杜絕空中連跳
Animator 設定
- 布林參數
run、jump - Clip:idle(1 張)、run(6 張,12 FPS)、jump(1 張)
- idle ⇄ run、Any State → jump ⇄ idle
- 每條轉場:取消 Has Exit Time、Duration = 0
向左移動時設定
spr.flipX = true,避免角色「月球漫步」;左右兩側加透明空氣牆(Alpha = 0)擋住角色。無限隨機地形與難度遞增
GroundMove地面向左移動,
Translate × Time.deltaTime 達成幀率獨立;x ≤ -25 時 DestroyPrefab地面含腳本、碰撞器與 Ground Tag,生成即繼承設定
GroundMaker陣列存多種 Prefab,
InvokeRepeating 定時以隨機索引與間距 Instantiate越跑越快
計數器groundCount % 10 == 0 時執行 GroundMove.speed *= 1.5f;static 變數讓全場景地形同步加速。防滑行
踏上地面SetParent(other.transform),離開 SetParent(null),角色隨平台移動。陷阱:縮放變形
地形 Prefab 的 Transform Scale 必須是 (1,1,1);要改大小請調 SpriteRenderer 或 Collider 尺寸。動態開場、流程管理與音效
AI 動態封面
- Kling「新增結束畫格」:起始=天空、結束=標題圖,生成 6 秒開場
- Video Player → Render Texture (1920×1080) → Raw Image
- Canvas 用 Scale with Screen Size;關閉 Skip Frames
GameManager 狀態開關
- Pre-game:player、ground、groundMaker 先停用
- 按 Enter →
StartGame():關閉標題、啟用核心物件、切換音樂
AudioManager
- Suno 生成無人聲電子樂:titleMusic、bgm
Awake()先取得 AudioSource,Start()才能安全呼叫播放,避免 NullReference
死亡、計分與打包
陷阱一:static 不會自動重置
LoadScene() 不會還原 static 變數。要在 GameManager 的 Start() 明確寫 GroundMove.speed = 5f,否則重玩仍是死前高速。陷阱二:最終分數持續跳動
用isGameOver 鎖定:偵測到 player.isDead 且未結算時才執行 TriggerGameOver() 並立刻上鎖。計分與死亡線
底部 Death Line(Is Trigger,Tag = Deathline);距離 += speed × deltaTime,TMP 顯示{distance:F0} m。1 圖示1024×1024 PNG
2 Default IconProject Settings → Player
3 Build Profiles確認場景已勾選
4 Build輸出 PixelDash.exe