Toán học là nền tảng không thể thiếu trong phát triển game. Dưới đây là hướng dẫn step-by-step về 4 khái niệm toán học thường dùng nhất trong Unity, đi kèm theo vấn đề thực tế, giải thích, code demo và phân tích chi tiết.
1. Vector (Vector2, Vector3) – Vị trí và Không gian
Vấn đề cần giải quyết:
Làm thế nào để xác định vị trí của vật thể, đo khoảng cách giữa 2 vật thể, hoặc tìm hướng để một vật thể đi về phía vật thể khác?
Giải thích khái niệm:
- ● Vector3 là một tập hợp gồm 3 con số (x, y, z) để mô tả không gian 3 chiều (3D). Trong 2D ta dùng Vector2 (x, y).
- ● Trong Unity, Vector thường đại diện cho Vị trí (Tọa độ) hoặc Hướng di chuyển (Direction).
Demo: Tính khoảng cách và di chuyển Player về phía Enemy
Khi Player muốn đuổi theo Enemy, ta cần tìm khoảng cách và vector hướng.
**Giải thích tham số và dòng lệnh:**
- ● Vector3.Distance(a, b): Trả về một số thực (float) là khoảng cách ngắn nhất giữa tọa độ a và b.
- ● enemy.position – player.position: Công thức Toán học kinh điển: Vector chỉ hướng = Điểm Đích – Điểm Xuất Phát.
- ● .normalized: Ép độ dài (magnitude) của vector về chính xác 1 mà vẫn giữ nguyên hướng. Điều này rất quan trọng để khi nhân với speed, tốc độ di chuyển luôn ổn định.
- ● Time.deltaTime: Thời gian trôi qua giữa 2 frame. Giúp tốc độ di chuyển không bị ảnh hưởng bởi FPS.
2. Nội Suy Tuyến Tính (Lerp) – Chuyển động mượt mà
Vấn đề cần giải quyết:
Làm thế nào để một thanh máu (UI Slider) giảm từ từ khi nhân vật bị mất máu thay vì tụt “cái rụp”?
Giải thích khái niệm:
Lerp (Linear Interpolation) là phép toán tìm ra một giá trị nằm giữa 2 điểm A và B, dựa trên một tỷ lệ phần trăm t (từ 0.0 đến 1.0).
Ví dụ: A = 0, B = 10. Nếu tỷ lệ t = 0.5 (50%) thì hàm Lerp sẽ trả về kết quả là 5.
Với UI, ta sẽ dùng Mathf.Lerp để nội suy một con số (float) thay vì Vector3.Lerp.
Demo: Thanh máu giảm mượt mà (Smooth Health Bar)
**Giải thích tham số và dòng lệnh:**
Mathf.Lerp(float a, float b, float t):
- ● a: Giá trị đang hiển thị hiện tại (healthSlider.value).
- ● b: Lượng máu thực tế (currentHealth).
- ● t: Tốc độ nội suy (lerpSpeed * Time.deltaTime).
– `healthSlider.value`: Truy cập vào thuộc tính value của Slider, thông thường ta thiết lập Max Value là 100 trong Inspector.
– `Time.deltaTime`: Luôn có mặt để đảm bảo tốc độ tụt máu luôn đồng đều bất kể máy tính chạy ở FPS cao hay thấp.
3. Lượng Giác Học (Trigonometry: Sin & Cos)
Vấn đề cần giải quyết:
Bạn muốn một đồng xu bay lơ lửng nhấp nhô (bobbing), hoặc một vật thể di chuyển theo quỹ đạo hình tròn?
Giải thích khái niệm:
Hàm Sin() và Cos() trả ra một con số tuần hoàn nhịp nhàng trong khoảng từ -1 đến 1.

Demo: Đồng xu lơ lửng nhịp nhàng (Floating Item)
Giải thích tham số và dòng lệnh:
- ● Time.time: Thời gian tính bằng giây kể từ lúc bắt đầu game.
- ● Mathf.Sin(giá trị): Trả về một giá trị sóng từ -1 đến 1.
– `Mathf.PI`: Trị số Pi (~3.14). Được dùng để làm tròn nhịp điệu (VD: `frequency = 1` thì đúng 2 giây vật sẽ nhấp nhô đủ 1 vòng tròn).
- ● amplitude: Biên độ dao động.
4. Quaternions – Xoay Vật Thể Không Lỗi
Vấn đề cần giải quyết:
Bạn muốn nòng súng của trụ phòng thủ (Turret) tự động quay về hướng kẻ địch một cách từ từ và mượt mà.
Giải thích khái niệm:
- ● Góc xoay hiển thị bằng Euler Angles (0 – 360).
- ● Unity dùng Quaternion (x,y,z,w) để tránh lỗi Gimbal Lock.
– **Quy tắc Vàng:** Không bao giờ thay đổi các giá trị x, y, z, w của Quaternion bằng tay trừ khi bạn là một chuyên gia toán học. Luôn dùng các hàm có sẵn của Unity.
Demo: Tháp pháo quay nòng bám sát mục tiêu
Giải thích tham số và dòng lệnh:
- ● Quaternion.LookRotation: Quy đổi Vector hướng sang góc xoay.
- ● Quaternion.Slerp: Nội suy góc xoay mượt mà.
– `transform.rotation`: Biến lưu trữ góc xoay hiện tại của vật thể dưới dạng Quaternion. Ta gán nó bằng kết quả của hàm Slerp để cập nhật góc xoay mỗi frame.
Demo 2: Kim đồng hồ quay liên tục 360 độ (Góc Euler)
Bên cạnh Quaternion, nếu bạn chỉ muốn xoay một vật thể liên tục theo một trục cố định (như kim đồng hồ, cánh quạt, bánh xe), việc dùng hàm `transform.Rotate` với góc Euler sẽ đơn giản và hiệu quả hơn rất nhiều.
**Giải thích tham số và dòng lệnh:**
– `transform.Rotate(x, y, z)`: Cộng dồn thêm một góc quay (tính bằng Độ) vào góc quay hiện tại của vật thể. Hàm này tự động xử lý chuyển đổi Euler sang Quaternion an toàn ở bên dưới.
– `-rotationSpeed`: Dấu trừ (`-`) giúp vật xoay thuận chiều kim đồng hồ.
– `Time.deltaTime`: Nhờ nhân với tham số này, kim đồng hồ sẽ luôn quay chuẩn xác `90` độ trong đúng `1` giây ngoài đời thực, bất kể tốc độ khung hình (FPS) nhanh hay chậm.
Demo 3: Xoay quanh một tâm điểm bất kỳ (Pivot)
Nếu bạn không muốn xoay quanh tâm của chính vật thể đó (như kim đồng hồ) mà muốn xoay quanh một mục tiêu khác (ví dụ: Trái Đất quay quanh Mặt Trời), Unity hỗ trợ sẵn hàm `transform.RotateAround`.
**Giải thích tham số và dòng lệnh:**
– `transform.RotateAround(Vector3 point, Vector3 axis, float angle)`:
– `point`: Tọa độ 3D của tâm điểm bạn muốn vật xoay quanh. Trong demo là vị trí của vật thể `pivot`.
– `axis`: Trục mà bạn muốn xoay quanh. Nếu Trái Đất quay quanh Mặt Trời trên mặt phẳng ngang thì trục xoay là thẳng đứng lên trời (`Vector3.up` hay `new Vector3(0, 1, 0)`). Nếu làm game 2D thì trục quay thường là đâm xuyên màn hình `Vector3.forward` (trục Z).
– `angle`: Số độ xoay cộng thêm vào mỗi frame (`orbitSpeed * Time.deltaTime`).
Mẹo nhỏ cho thiết kế (Không cần code thêm)
> Nếu bạn không muốn viết code dùng `RotateAround`, cách phổ biến trong Unity là tạo một **GameObject rỗng** (Empty GameObject) đặt ngay tại điểm tâm quay. Sau đó, trong cửa sổ Hierarchy, kéo vật thể cần xoay vào làm **Con (Child)** của GameObject rỗng đó. Từ lúc này, bạn chỉ cần cho GameObject rỗng đó tự xoay quanh tâm nó (bằng Demo 2), thì tự khắc thằng con sẽ bị kéo xoay vòng tròn bay quanh thằng cha (giống như Mặt Trời xoay kéo Trái Đất quay theo).








