Làm game platformer pixel art với Unity 6
Mười bảy bài từ một sprite tới build WebGL: tilemap, cú nhảy tính bằng công thức, ScriptableObject, địch, boss, juice, và cách tự tìm lỗi Unity không báo
- 0Platformer #0: Đưa pixel art vào Unity mà không bị phá
Import mặc định của Unity làm sprite mờ, đổi màu 97% số pixel, và trong template 3D còn co file 352×32 xuống 256×32. Bài này sửa import, chọn PPU 16, đặt pivot ở chân và khoá camera đúng 32×18 tile.
19 min read - 1Platformer #1: Một căn phòng vẽ bằng một viên gạch
Dựng RuleTile 15 rule để Unity tự chọn ô góc, ô cạnh, rồi vẽ căn phòng 64×36 tile bằng đúng một tile. Gộp 528 collider vuông thành một đường bao liền để nhân vật không vấp.
14 min read - 2Platformer #2: Chạy, và vì sao Rigidbody để Dynamic
Đưa nhân vật vào phòng, để vật lý lo trọng lực và va chạm, còn code chỉ lo vận tốc ngang. Tăng tốc 0.12 s, dừng 0.08 s, nhả phím trượt thêm 0.27 unit, tất cả đo được.
13 min read - 3Platformer #3: Nhảy cao đúng 5 ô, tính chứ không mò
Muốn nhảy cao 5 ô thì đặt lực bao nhiêu? Bài này suy trọng lực và vận tốc nhảy từ hai con số thiết kế, rồi thêm nhảy thấp khi nhả sớm, coyote time và jump buffer. Mọi con số đều đo lại được.
15 min read - 4Platformer #4: Double jump và wall jump, một phím ba kết quả
Cùng một phím Space: nhảy từ đất, bật tường, hay nhảy thêm giữa không trung. Thứ tự kiểm tra quyết định cảm giác, và 0.15 giây khoá hướng là thứ giúp nhân vật thật sự bật ra khỏi tường.
13 min read - 5Platformer #5: Camera đi theo nhân vật mà không lộ ra ngoài phòng
Camera bám nhân vật trong căn phòng 64×36, nhảy tại chỗ thì đứng yên, chạy tới tường thì dừng đúng mép phòng. Dựng từng lớp một, và một lỗi thứ tự clamp mà hầu hết code camera đều mắc.
16 min read - 6Platformer #6: Animation chọn theo vật lý, Animator không có mũi tên nào
Bảy animation cho nhân vật mà Animator không có một transition nào. Trạng thái animation được suy ra từ vận tốc, chạm đất, bám tường của motor, nên thêm động tác mới chỉ cần thêm một dòng code.
13 min read - 7Platformer #7: Ba nhân vật, ba cảm giác, một prefab
Tách 19 con số cảm giác điều khiển ra khỏi motor thành một ScriptableObject. Ba asset cho ba nhân vật: một chạy nhanh nhảy cao, một nặng trượt dài không có double jump. Đổi asset là đổi cả hình lẫn tay cầm.
13 min read - 8Platformer #8: Chết và hồi sinh mà không load lại scene
Bẫy, checkpoint, và một chuỗi chết rồi hồi sinh 0.8 giây không cần load lại scene. Collider của bẫy phải đo từ hình vẽ, và 1.2 giây bất tử sau khi hiện ra để không rơi vào vòng lặp chết.
18 min read - 9Platformer #9: Ngọc, thùng gỗ, cửa thoát và bảng va chạm
Cho căn phòng một mục tiêu: nhặt đủ 5 viên ngọc thì cửa mở. Một luật giẫm dùng chung cho thùng và địch, collider thùng đo theo hình vẽ, bộ đếm ngọc đứng im vì thứ tự hai dòng code, và ô bảng va chạm làm cả màn chơi không thắng được mà không có lỗi nào.
22 min read - 10Platformer #10: Địch đi tuần mà không rơi khỏi bệ
Hai cảm biến nhìn về phía trước: một tia dò sàn và một hộp dò tường. Địch Kinematic đi bằng MovePosition, quay đầu đúng mép bệ với sai số 0.04 unit, chết khi bị giẫm bằng đúng luật StompCheck của bài 9, và giết người chơi khi chạm ngang.
15 min read - 11Platformer #11: Ba kiểu địch từ một ScriptableObject
Charger lao tới rồi choáng khi đâm tường, khẩu pháo bắn đạn lấy từ object pool của series shmup, con bay bổ nhào xuống đầu. Ba hành vi khác hẳn nhau đọc số từ cùng một kiểu EnemyData, và sáu lỗi code vẫn chạy mà không làm gì.
26 min read - 12Platformer #12: Boss thắng bằng chân, không bằng vũ khí
Nhân vật không có đòn đánh, nên boss phải tự đặt mình vào thế hở: khựng lại, lao tới, đâm vách, thở dốc. Ba lần giẫm, nhịp nhanh dần sau mỗi lần trúng. Collider đặt theo thân chứ không theo ô 72 pixel, và một lỗi làm người chơi chết ngay sau cú giẫm trúng.
16 min read - 13Platformer #13: Rung, chớp, âm thanh, không sửa dòng gameplay nào
Một lớp phản hồi gắn từ bên ngoài: nghe sự kiện mà mười hai bài trước đã phát sẵn, biến chúng thành rung camera, tiếng động, chớp màu và nhấp nháy lúc bất tử. Tắt nó đi thì game vẫn đúng mọi luật, chỉ im lặng. Và một cú rung boss bị nuốt mất vì đọc máu quá sớm.
16 min read - 14Platformer #14: Nền cuộn vô hạn, làm bằng shader rồi bỏ shader
Nền lát vô hạn, tự trôi, trôi chậm hơn thế giới. Bản đầu là một shader tính UV từ toạ độ thế giới, chạy đúng nhưng bắt mình tự làm lại ba việc đường render sprite đã làm sẵn. Bản đang dùng chỉ là một sprite lát gạch được kéo về mỗi khi đi hết một ô. Và vì sao nền trông nhòe mà thật ra không nhòe.
13 min read - 15Platformer #15: Nhiều màn, chọn nhân vật, HUD và build lên web
Biến căn phòng lab thành thứ người lạ mở lên chơi được: ba màn nối nhau trong một asset, tiến trình lưu trong PlayerPrefs, màn chọn nhân vật dùng lại ScriptableObject của bài 7, HUD đếm ngọc và thanh máu boss giữ nguyên góc pixel. Rồi build WebGL, với một danh sách sáu dòng mà dòng nào cũng từng làm mình mất thời gian.
22 min read - 16Platformer #16: Những lỗi không hiện trong Console, và ba công cụ để bắt chúng
Một script soát cả 18 scene in ra CLEAN. Người đầu tiên mở game lên chơi không qua nổi màn 1. Bài cuối không phải danh sách lỗi đã sửa mà là cách soát: đọc alpha thật của sprite, hỏi thẳng bảng va chạm, và chơi bằng input thật thay vì gọi API. Và bảy lỗi nữa mình tìm ra khi viết lại cả series.
17 min read