Dựa trên cấu trúc Animator bạn đang xây dựng với rất nhiều hành động đa dạng (Run, Hurt, Climb, Roll, Crouch, LookUp…), bài viết này sẽ hướng dẫn bạn từng bước cách quy hoạch lại Animator sao cho chuẩn xác, dễ quản lý và không bị lỗi “mạng nhện” (Spider web). Đặc biệt, tôi đã bổ sung thêm phần thiết lập trạng thái **Nhảy (Jump)** và **Rơi (Fall)** không thể thiếu cho game đi cảnh.

Bước 1: Khai báo Animator Parameters (Biến điều kiện)
Để điều khiển mượt mà số lượng lớn trạng thái này, chúng ta cần chia các Parameter ra thành từng nhóm cụ thể. Mở tab **Parameters** trong cửa sổ Animator và tạo các biến sau:
QUAN TRỌNG: Trigger dùng cho các hành động xảy ra chớp nhoáng 1 lần. Bool dùng cho các hành động kéo dài (giữ phím). Float dùng cho tốc độ/hướng.
- Speed (Float): Kiểm tra tốc độ di chuyển trái/phải.
- VelocityY (Float): Kiểm tra vận tốc trục Y để biết đang nhảy lên hay rơi xuống.
- IsGrounded (Bool): Kiểm tra xem nhân vật có đang chạm mặt đất không.
- IsCrouching (Bool): Kiểm tra xem nhân vật có đang cúi người không.
- IsClimbing (Bool): Kiểm tra xem nhân vật có đang bám tường/leo thang không.
- Roll (Trigger): Kích hoạt cuộn người.
- Hurt (Trigger): Kích hoạt khi bị thương.
Bước 2: Tối ưu hóa các trạng thái Bị Động (Hurt, Dizzy) bằng Any State
Các trạng thái như bị đánh trúng (Hurt) hoặc choáng váng (Dizzy) có thể xảy ra bất cứ lúc nào (khi đang chạy, đang nhảy, hoặc đang đứng). Nếu nối chúng từ `Idle`, nhân vật sẽ không thể bị thương khi đang bay trên không!
- Xóa hết các mũi tên nối từ Idle sang Hurt01, Hurt02 (Chuột phải vào mũi tên -> Delete).
- Click chuột phải vào nút xanh ngọc Any State -> Make Transition -> Nối vào Hurt01.
- Nhấp vào mũi tên từ Any State -> Hurt01, thiết lập Inspector:
- Has Exit Time: Bỏ tích.
- Transition Duration: 0
- Conditions: Bấm dấu +, chọn Hurt (Trigger).
4.Tạo mũi tên từ Hurt01 quay về Idle (Để sau khi hoạt ảnh đau đớn kết thúc, nhân vật đứng dậy):
- Has Exit Time: Tích vào (Nghĩa là phải chờ animation chạy xong).
- Exit Time: 1 (Chạy hết 100% clip bị thương).
- Transition Duration: 0
- Conditions: Bỏ trống.
Bước 3: Thiết lập trạng thái Nhảy & Rơi (Jump & Fall)
Trong game 2D, chúng ta phân biệt nhảy và rơi dựa vào vận tốc trục Y. Nếu Y > 0 là đang bay lên (Jump), Y < 0 là đang rớt xuống (Fall). Bằng cách dùng **Any State**, nhân vật có thể nhảy dù đang đứng hay đang chạy.
1. Nhảy lên (Jump)
– **Any State -> Jump**:
- Has Exit Time: False | Duration: 0
- Conditions: IsGrounded = false, VelocityY Greater 0.1

2. Rơi xuống (Fall)
– **Any State -> Fall** (hoặc Jump -> Fall):
- Has Exit Time: False | Duration: 0
- Conditions: IsGrounded = false, VelocityY Less -0.1

3. Chạm đất (Về Idle hoặc Run)
Khi chạm đất, Animator sẽ tự hiểu thông qua biến `IsGrounded`. Ta nối trực tiếp từ Fall (hoặc Any State) về Idle.
– **Fall -> Idle**:
- Has Exit Time: False | Duration: 0
- Conditions: IsGrounded = true
Bước 4: Thiết lập các trạng thái Di Chuyển & Cúi Người (Bool & Float)
1. Idle <-> Run
– **Idle -> Run**:
- Has Exit Time: False | Duration: 0
- Conditions: Speed Greater 0.1
– **Run -> Idle**:
- Has Exit Time: False | Duration: 0
- Conditions: Speed Less 0.1

2. Idle <-> Crouch (Cúi người)
– **Idle -> Crouch**:
- Has Exit Time: False | Duration: 0
- Conditions: IsCrouching = true
– **Crouch -> Idle**:
- Has Exit Time: False | Duration: 0
- Conditions: IsCrouching = false
Bước 5: Thiết lập các trạng thái Hành Động Đơn (Trigger)
Hành động đơn như **Roll** (Cuộn người) nên được kích hoạt bằng **Trigger**. Giống như Hurt, nó sẽ tự quay về Idle khi hoàn thành.
- Nối Idle -> Roll và Run -> Roll.
- Cài đặt mũi tên tiến (vào Roll):
- Has Exit Time: False | Duration: 0
- Conditions: Roll (Trigger)
3.Nối Roll -> Idle:
- Has Exit Time: True (Bắt buộc, để cuộn xong mới đứng lên).
- Exit Time: 1 | Duration: 0
- Conditions: Bỏ trống.
Bước 6: Cấu trúc Code C# Điều khiển Nâng cao (Bao gồm Nhảy)
Để điều khiển hệ thống Animator phức tạp này cùng với chức năng nhảy, hãy cập nhật script `AdvancedFoxController.cs` của bạn:





MẸO: Cách thiết lập Ground Check cho chức năng nhảy:
- Tạo một GameObject rỗng con của Fox, đặt tên là GroundCheck.
- Kéo nó xuống ngang bằng với bàn chân của Fox.
- Trong script AdvancedFoxController, kéo GroundCheck vào ô tương ứng.
- Tạo một Layer mới tên là Ground, gán Layer này cho các viên gạch/mặt đất trong game.
- Chọn ô Ground Layer trong script là Ground.

Tóm tắt quy trình hoạt động mới
- Nhảy & Rơi: Bấm Space, nhân vật vọt lên (VelocityY > 0), Animator tự qua trạng thái Jump. Tới đỉnh điểm lực hút trái đất kéo xuống (VelocityY < 0), tự đổi sang Fall. Chạm đất, Animator tự về Idle hoặc Run.
- Bất kể bạn đang làm gì, nếu gọi hàm TakeDamage(), Trigger Hurt sẽ lập tức ép Animator ngắt mọi thứ để chuyển sang hoạt ảnh bị thương, sau đó mới từ từ quay lại Idle.
Chúc các bạn thành công!
Giảng viên Nguyễn Hữu Huy
Bộ môn Công nghệ thông tin
FPT Polytechnic Hà Nội

