Unity Term Book
Core & Architecture

Tag & Layer

Tag gán nhãn định danh GameObject cho script (CompareTag); Layer nhóm đối tượng để kiểm soát Physics collision, Camera culling và Raycast LayerMask trong Unity.

Hãy tưởng tượng...

Tag giống như huy hiệu tên đeo trên áo — "Player", "Enemy", "Treasure" — để bảo vệ viên có thể nhận ra và xử lý ngay (CompareTag). Layer giống như khu vực được phân vạch trong tòa nhà — Nhân viên chỉ vào được tầng mình được cấp quyền (Camera Culling Mask), và các phòng quyết định phòng nào có thể tương tác vật lý với nhau (Physics Layer Collision Matrix).

Khái niệm chi tiết

Tag là chuỗi string gán cho một GameObject (mỗi GO chỉ có 1 tag). Dùng gameObject.CompareTag(“Player”) thay vì gameObject.tag == “Player” để tránh cấp phát bộ nhớ. Các tag mặc định: Untagged, Respawn, Finish, EditorOnly, MainCamera, Player, GameController.

Layer là số nguyên 0–31 (32 layer tối đa). Mỗi Layer được đại diện bởi một bit trong LayerMask (bitmask 32-bit). Layer điều khiển: (1) Camera Culling Mask — Camera chỉ render Layer được chọn; (2) Physics Layer Collision Matrix — thiết lập layer nào va chạm với layer nào; (3) Raycasting LayerMask — ray chỉ hit object thuộc layer cho phép.

LayerMask: LayerMask.GetMask(“Enemy”, “NPC”) trả về bitmask kết hợp nhiều layer. Dùng toán tử ~ để đảo mask (exclude layer): ~LayerMask.GetMask(“Player”) = mọi layer trừ Player.

Thực hành tốt: đặt tên Layer theo chức năng (không phải tên object), tạo trong Edit → Project Settings → Tags and Layers. Ví dụ: Ground, Projectile, Interactable, UI, PostProcess.

So sánh: Tag vs Layer

🏷 Tag

Mục đích

Nhận diện loại đối tượng trong script (CompareTag)

Số lượng

Không giới hạn (string), mỗi GO chỉ có 1 tag

Ứng dụng

OnTriggerEnter, FindWithTag, so sánh trong script

Ví dụ

PlayerEnemyTreasure

📚 Layer

Mục đích

Nhóm đối tượng cho Physics & Camera rendering

Số lượng

Tối đa 32 layer (0-7 dành cho Unity), bit 0–31

Ứng dụng

Culling Mask, Collision Matrix, Raycast LayerMask

Ví dụ

GroundProjectileUI

Hướng dẫn thực hành

1

Tạo Tag/Layer mới

Edit → Project Settings → Tags and Layers. Thêm vào mảng Tags hoặc Layers.

2

Gán cho GameObject

Chọn GO trong Hierarchy → Inspector → dropdown Tag hoặc Layer ở đầu trang.

3

Cấu hình Collision Matrix

Edit → Project Settings → Physics → Layer Collision Matrix → bỏ tick layer không cần va chạm nhau.

4

Cài Camera Culling Mask

Chọn Camera → Inspector → Culling Mask → chọn layer cần render (UI Camera chỉ cần render layer UI).

5

Dùng LayerMask trong Raycast

Physics.Raycast(origin, dir, distance, LayerMask.GetMask("Ground")) — chỉ hit layer Ground.

Trình mô phỏng tương tác

Click vào GameObject để chọn. Thay đổi Tag và Layer. Xem Collision Matrix và kiểm tra Raycast.

Hierarchy

Chọn một GameObject

Selected: None|Click một GameObject để chỉnh Tag/Layer

Ví dụ Code

Cơ bản

Sử dụng Tag để nhận diện đối tượng trong OnTriggerEnter.

using UnityEngine;

public class TreasureChest : MonoBehaviour
{
  private void OnTriggerEnter(Collider other)
  {
      // CompareTag không cấp phát string — tốt hơn == operator
      if (other.CompareTag("Player"))
      {
          Debug.Log("Player đã nhặt rương kho báu!");
          gameObject.SetActive(false);
      }
  }
}

// Tìm tất cả Enemy trong scene theo Tag
GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy");
foreach (var e in enemies) e.GetComponent<EnemyAI>().Alert();

Ví dụ Code

Nâng cao

LayerMask trong Raycast và quản lý layer động.

using UnityEngine;

public class PlayerGroundCheck : MonoBehaviour
{
  [SerializeField] private float checkDistance = 0.1f;

  // Tạo LayerMask từ tên layer — cache tránh gọi lặp
  private readonly int _groundMask = LayerMask.GetMask("Ground", "Platform");

  public bool IsGrounded =>
      Physics.Raycast(transform.position, Vector3.down, checkDistance, _groundMask);

  void Update()
  {
      if (IsGrounded)
          GetComponent<Rigidbody>().drag = 5f;   // ma sát khi đứng
      else
          GetComponent<Rigidbody>().drag = 0f;   // không lực cản khi trên không
  }

  // Đổi Layer lúc runtime (ví dụ: tàng hình qua tường)
  public void SetGhostMode(bool ghost)
  {
      gameObject.layer = LayerMask.NameToLayer(ghost ? "Ghost" : "Player");
  }
}

📌 Ghi nhớ nhanh

  • Tag = nhận diện bằng script; Layer = kiểm soát Physics và Camera
  • Dùng CompareTag() thay vì tag == để tránh GC alloc
  • LayerMask là bitmask — dùng GetMask() thay vì số cứng
  • Tối đa 32 layer; bỏ tick Collision Matrix để skip va chạm không cần thiết

⚠️ Lỗi thường gặp

  • ❌ Dùng gameObject.tag == "Player"

    Tạo string allocation mỗi lần gọi, gây GC pressure

    ✅ gameObject.CompareTag("Player")

  • ❌ Hardcode số layer: layerMask = 8

    Dễ sai khi layer order thay đổi

    ✅ LayerMask.GetMask("Ground")