--------------- <> -----------------
--- KHOA HỌC - CÔNG NGHỆ - GIÁO DỤC - VIỆC LÀM ---
--- Học để đi cùng bà con trên thế giới ---

Tìm kiếm trong Blog

Unity (5) - Colliders

Bài trước: Unity (4) - Hệ thống vật lý
-----

5. Colliders

Ở bài học trước, bạn đã được làm quen với khái niệm Rigidbody, làm một thành phần của Hệ thống vật lý. Khi thêm thành phần Rigidbody vào một đối tượng game, nó sẽ giúp đối tượng game có các thuộc tính vật lý như trọng lực, lực va chạm, lực đẩy. 

Phần này, chúng ta sẽ tiếp tục tìm hiểu một thuộc tính vật lý khác là Colliders.

5.1 Colliders là gì?

Collide: nghĩa là va chạm.

Collider: nghĩa là Bộ va chạm.

Khi một đối tượng game đã được gắn Rigidbody, nếu nó va chạm với một đối tượng khác nó sẽ bị bật ra. Tuy nhiên, khi nào thì biết được nó đã chạm vào đối tượng khác? Collider sẽ giúp đối tượng game có được khả năng này.

Nếu Rigidbody là "linh hồn" giúp đối tượng có trọng lực và sức mạnh, thì Colliders chính là "da thịt" hoặc "lớp vỏ", giúp đối tượng biết khi nào mình chạm vào thứ gì đó.

Trong thế giới thực, hai vật thể không thể đi xuyên qua nhau vì chúng có cấu trúc vật chất. Trong Unity, các đối tượng (GameObject) mặc định chỉ là những hình ảnh hoặc mô hình 3D rỗng, chúng sẽ đi xuyên qua nhau, trừ khi bạn gắn cho chúng một Collider.

Collider là một thành phần (component) bao quanh đối tượng, định nghĩa hình dáng của nó cho mục đích vật lý. Nó tạo ra một "vùng va chạm" để Unity biết khi nào hai vật thể tiếp xúc với nhau.

Các loại Collider phổ biến:

- Box Collider: Hình hộp (dùng cho tường, thùng, nền nhà)

- Sphere Collider: Hình cầu (dùng cho quả bóng, vật tròn)

- Capsule Collider: Hình viên thuốc “con nhộng” (thường dùng cho nhân vật người)

- Mesh Collider: Hình dạng phức tạp khớp hoàn toàn với mô hình 3D

5.2. Trigger và Collision

Trong thành phần Collider của Unity có một ô chọn quan trọng tên là Is Trigger. Tùy vào việc ô này được chọn hay không, đối tượng sẽ hoạt động theo một trong hai cơ chế sau:

Collision

Collision có nghĩa là va chạm vật lý thực sự. Nó giống như khi bạn vô tình cụng đầu vào bức tường: bạn bị chặn lại, bị đau và có thể bị bật ngược lại.

Đặc điểm:

- Tính chất: Các đối tượng không thể đi xuyên qua nhau. Chúng có sự tương tác về lực, khối lượng và ma sát

- Ứng dụng: Dùng khi bạn muốn có sự va chạm cơ học như: bắn nhau (viên đạn nảy ra), đâm xe, nhân vật đứng trên mặt đất, quả bóng nảy trên tường

- Thiết lập: Ô Is Trigger trong Component Collider không chọn

Unity cung cấp 3 hàm chính:

- OnCollisionEnter: Chạy đúng 1 lần ngay khi vừa chạm vào nhau. Ví dụ tiếng nổ khi viên đạn chạm tường

- OnCollisionStay: Chạy liên tục mỗi khung hình khi đang tiếp xúc. Ví dụ nhân vật bị mất máu dần khi đứng trên bàn chông

- OnCollisionExit: Chạy đúng 1 lần ngay khi vừa tách nhau ra

Trigger

Trigger có nghĩa là vùng kích hoạt/cảm biến. Nó giống như khi bạn đi qua cửa tự động: bạn đi xuyên qua tia hồng ngoại (vùng cảm biến), cửa nhận diện được bạn và tự động mở ra mà không ngăn cản bước đi của bạn.

Đặc điểm:

- Tính chất: Các đối tượng có thể đi xuyên qua nhau. Nó chỉ đóng vai trò là một "vùng không gian" để nhận biết sự hiện diện của đối tượng khác

- Ứng dụng: Dùng để tạo vùng nhặt vật phẩm (vàng, máu), vùng kết thúc màn chơi, vùng phát hiện kẻ địch, hoặc các khu vực kích hoạt sự kiện

- Thiết lập: Ô Is Trigger trong Component Collider phải được chọn

Unity cung cấp 3 hàm chính:

- OnTriggerEnter: Chạy khi vừa bước vào vùng. Ví dụ: Hiển thị dòng chữ "Bạn đã vào khu vực nguy hiểm"

- OnTriggerStay: Chạy liên tục khi đang ở trong vùng. Ví dụ: Mỗi giây hồi 5 HP khi đứng trong vòng hồi máu

- OnTriggerExit: Chạy khi vừa bước ra khỏi vùng. Ví dụ: Đóng cửa khi người chơi đã đi qua

5.3. Game "Hứng kim cương"

Để hiểu rõ cách Collider hoạt động, chúng ta sẽ thực hiện một ví dụ nhỏ: Một viên kim cương rơi từ trên cao xuống, nếu chạm đất thì biến mất, nếu chạm vào người chơi thì cộng điểm.

Bước 1: Chuẩn bị môi trường

Trong giao diện của Unity Editor > Khung Hierarchy > trong mục Main Camera đang có các đối tượng game của ví dụ trước. Để vô hiệu các đối tượng này, bạn chọn đối tượng > trong khung Inspector > bỏ dấu chọn phía trái (ngay cạnh tên đối tượng).

1. Tạo đối tượng mặt đất (Ground):

Tại khung Hierarchy > chuột phải vào vùng trống > 3D Object > Cube > đặt tên là Ground. Mặc định Cube đã có Box Collider. Kéo dài Ground theo chiều ngang để tạo thành mặt đất: chọn đối tượng Ground > chọn Edit bounding volume > dùng chuột chỉnh chiều ngang/dọc trên đối tượng. 

2. Tạo đối tượng người chơi (Player):

Tại khung Hierarchy > chuột phải vào vùng trống > 3D Object > Sphere > đặt tên là Player.

3. Tạo viên kim cương (Diamond):

Tại khung Hierarchy > chuột phải vào vùng trống > 3D Object > Capsule > đặt tên là Diamond. Gắn thêm Rigidbody cho Diamond để nó có thể rơi xuống (vào mục Add Component > chọn Rigidbody).

Bước 2: Thiết lập va chạm

- Ground: Để nguyên Box Collider. Ô Is Trigger: không chọn (tắt)

- Player: Để nguyên Sphere Collider. Ô Is Trigger: không chọn (tắt)

- Diamond: Tại thành phần Capsule Collider, hãy tích vào ô Is Trigger. Lý do: Chúng ta muốn viên kim cương có thể đi xuyên vào người chơi để tạo cảm giác "ăn" được nó, thay vì bị nó rơi trúng đầu và nảy ra.

Bước 3: Viết mã xử lý va chạm

Tạo một Script C# tên là DiamondCollector và gắn vào đối tượng Diamond:

Tại cửa sổ Project > chuột phải vào mục Assets > Create > Scripting > Empty C# Script, đặt tên là DiamondCollector. Sau đó mở trình soạn mã nguồn lên và viết như sau:

[DiamonCollector.cs]

using UnityEngine;


public class DiamondCollector : MonoBehaviour

{

    // Hàm này tự động chạy khi có vật thể khác đi vào vùng Trigger của Kim cương

    private void OnTriggerEnter(Collider other)

    {

        // Kiểm tra xem vật thể chạm vào có tên là "Player" không

        if (other.gameObject.name == "Player")

        {

            Debug.Log("Đã thu thập kim cương! +10 điểm.");

            Destroy(gameObject); // Xóa viên kim cương khỏi màn hình

        }

    }


    // Hàm này chạy khi có va chạm vật lý thực sự (không tích chọn ô Is Trigger)

    private void OnCollisionEnter(Collision collision)

    {

        if (collision.gameObject.name == "Ground")

        {

            Debug.Log("Kim cương đã chạm đất và bị vỡ!");

            Destroy(gameObject);

        }

    }

}

Bước 4: Hoàn thiện trong Unity

1. Kéo Script DiamondCollector thả vào đối tượng Diamond

2. Mở cửa sổ Console

3. Nhấn nút Play

Chương trình bị lỗi:

Trong cửa sổ console, bạn chỉ thấy có dòng thông báo: Đã thu thập kim cương! + 10 điểm. Màn hình game màu xanh, có một ô tròn màu xám ở giữa. Không chơi được, không điều khiển được.

Cách sửa lỗi hiển thị (Màn hình xanh/Chỉ hiện Ground)

- Cấu trúc Hierarchy: Đưa các đối tượng Ground, Player, và Diamond ra khỏi Main Camera (nếu có). Chúng phải nằm độc lập trong Scene, không được làm "con" của Camera

- Tọa độ Trục Z: Đảm bảo tất cả vật thể (Ground, Player, Diamond) đều có Position Z = 0

- Vị trí Camera: Kiểm tra Main Camera có Position Z = -10 để nhìn thấy được các vật thể ở mốc 0

Thiết lập vật lý cho các đối tượng

- Ground (Mặt đất): Có Box Collider, không tích chọn ô "Is Trigger"

- Player (Người chơi): Có Sphere Collider, không tích chọn ô "Is Trigger". Có thành phần Rigidbody

- Diamond (Kim cương): Có Capsule Collider và phải tích chọn ô "Is Trigger" để có thể đi xuyên qua người chơi khi "ăn". Có thành phần Rigidbody và tích chọn Use Gravity để viên kim cương có thể rơi xuống.

Khi chạy lại chương trình, đã thấy viên kim cương rơi xuống. Tuy nhiên, không thấy mặt đất, và không điều khiển được người chơi.

Điều chỉnh vị trí các đối tượng

Điều chỉnh vị trí cho từng đối tượng trong bảng Inspector.

[1] Main Camera (Máy quay): Đây là "mắt" của người chơi. Nó cần lùi lại phía sau để nhìn thấy toàn bộ cảnh.

- Position: X = 0, Y = 1, Z = -10. Z = -10 là bắt buộc để camera không nằm đè lên vật thể

- Rotation: X = 0, Y = 0, Z = 0

[2] Player (Người chơi)

Nhân vật chính nên nằm ở tâm của màn hình

- Position: X = 0, Y = 0, Z = 0

- Scale: X = 1, Y = 1, Z = 1

- Lưu ý: Nếu bạn dùng khối Sphere (hình cầu), vị trí Y=0 sẽ làm một nửa người chơi chìm dưới mặt đất nếu mặt đất ở Y=0, nên chúng ta sẽ hạ mặt đất xuống thấp hơn.

[3] Ground (Mặt đất)

Mặt đất cần nằm dưới chân người chơi

- Position: X = 0, Y = -1, Z = 0

- Scale: X = 10, Y = 1, Z = 10

- Lưu ý: Tăng Scale X và Z lên 10 để tạo một mặt phẳng rộng giúp kim cương không bị rơi ra ngoài

[4] Diamond (Kim cương)

Kim cương cần bắt đầu từ trên cao để rơi xuống.

- Position: X = 0, Y = 5, Z = 0

- Scale: X = 0.5, Y = 0.5, Z = 0.5 (Làm nhỏ lại cho giống viên kim cương)

- Lưu ý: Trục X phải bằng 0 để nó rơi thẳng xuống đầu người chơi

Bước 5: Quan sát kết quả

Khi chạy, bạn sẽ thấy viên kim cương rơi trúng người chơi, và thông báo trong cửa sổ Console là: “Đã thu thập kim cương! +10 điểm”.

Xem hình sản phẩm game:



5.4 Bài tập và câu hỏi

Bài tập 5a. Cài đặt game Hứng kim cương.

Câu hỏi 5.1 Colliders trong Unity là gì? Phát biểu nào không đúng? 

A. Là "lớp vỏ" hoặc "da thịt" giúp đối tượng biết khi nào mình chạm vào thứ gì đó

B. Giúp định nghĩa hình dáng của đối tượng cho mục đích xử lý vật lý

C. Mặc định các đối tượng (GameObject) 3D khi tạo ra đã có khả năng ngăn cản vật khác đi xuyên qua mà không cần gắn Collider

D. Collider tạo ra một "vùng va chạm" để Unity nhận biết sự tiếp xúc giữa hai vật thể

Câu hỏi 5.2 Về cơ chế collision (va chạm vật lý) trong Unity, phát biểu nào không đúng? 

A. Các đối tượng không thể đi xuyên qua nhau và có sự tương tác về lực, ma sát

B. Để thiết lập cơ chế này, ô "Is Trigger" trong thành phần Collider phải được tích chọn

C. Được ứng dụng trong các trường hợp như xe đâm nhau hoặc nhân vật đứng trên mặt đất

D. Hàm OnCollisionStay sẽ chạy liên tục mỗi khung hình khi hai đối tượng đang tiếp xúc với nhau

Câu hỏi 5.3 Về cơ chế trigger (vùng kích hoạt) trong Unity, phát biểu nào không đúng? 

A. Các đối tượng có thể đi xuyên qua nhau, đóng vai trò như một vùng cảm biến

B. Thường được ứng dụng để tạo vùng nhặt vật phẩm (vàng, máu) hoặc vùng kết thúc màn chơi

C. Để sử dụng cơ chế này, ô "Is Trigger" trong thành phần Collider phải được tích chọn

D. Hàm OnTriggerEnter sẽ chạy liên tục mỗi khung hình, chừng nào đối tượng còn nằm trong vùng kích hoạt

-----
Bài sau: