Con người không thấu hiểu máy tính. Máy tính là một chiếc hộp ma thuật vạn năng. Con người tin tưởng những gì máy tính cho họ biết. Bruce Schneier
STDIO GameObject là một khái niệm cơ bản trong Unity. Mọi đối tượng trong game được hiển thị trong cửa sổ Hierarchy đều là các GameObject. Các loại đối tượng khác nhau sẽ có những thao tác đặc thù riêng, nhưng sẽ đều có những phương thức và thuộc tính chung của GameObject. Bài viết sẽ giới thiệu các thành phần chung nhất của một GameObject và các thao tác với C# Script.
Nội dung bài viết

Giới thiệu

GameObject là một khái niệm cơ bản trong Unity. Mọi đối tượng trong game, từ Camera đến các đối tượng UI, hay các đối tượng khác trong game được hiển thị trong cửa sổ Hierarchy đều là các GameObject. Các loại đối tượng khác nhau sẽ có những thao tác đặc thù riêng, nhưng là GameObject thì sẽ đều có những phương thức và thuộc tính chung của GameObject. Và đó chính là mục đích của bài viết – giới thiệu các thành phần chung nhất của một GameObject và các thao tác với C# Script.

Tiền đề bài viết

Bài viết thuộc Chương trình TỰ HỌC UNITY, sử dụng cho mục đích nghiên cứu cá nhân và training Unity.

Đối tượng hướng đến

Bài viết hướng đến đối tượng MỚI BẮT ĐẦU với Lập trình game trên Unity. Script hướng dẫn trong bài được viết bằng ngôn ngữ C# nên bạn đọc cần có kiến thức tương đối về C# để có thể đọc hiểu tốt.

Thuộc tính và hàm cơ bản

tag – name

Unity sử dụng hai cơ chế để lưu trữ và quản lý danh sách các GameObject, được hiển thị trong cửa sổ Hierarchy. Thuộc tính name được kế thừa lại từ lớp Object, lưu trữ tên của đối tượng được hiển thị ở Hierarchy.

Thuộc tính tag được sử dụng để phân loại và định danh các GameObject, phải được định nghĩa sẵn trước khi sử dụng. Các đối tượng chưa được phân loại sẽ được gắn mặc định tag “Untagged”. Để định nghĩa tag, ta có thể sử dụng Tag Manager tại cửa sổ Inspector của bất kỳ đối tượng nào.

ss_1

Chọn nút Add Tag, bấm chọn nút dấu + để thêm một tag mới và đặt tên cho nó:

ss_2

Name và Tag được sử dụng nhiều trong Script để chọn được đối tượng cần thao tác.

Lưu ý: Name không bắt buộc khác nhau giữa các đối tượng, nhưng tôi khuyến khích các bạn nên đặt tên cho mỗi đối tượng khác nhau để dễ phân biệt và xử lý trong Script. Cách đặt tên phổ biến là 1 tên chung và 1 index cho từng loại đối tượng.

Layer

Tại Tag Manager, chúng ta cũng có thể tạo ra các Layer và Sorting Layer để thuận tiện trong việc quản lý các đối tượng. Sorting Layer được sử dụng để phân lớp hiển thị các đối tượng và sử dụng với thành phần SpriteRenderer.

Layer được sử dụng để phân lớp đối tượng và tuỳ chọn hiển thị trong Camera. Một số lớp được Unity tạo sẵn cơ bản là đủ với các nhu cầu thông thường của lập trình viên.

Active

Hai thuộc tính activeInhierarchy activeSelf được sử dụng để kiểm tra trạng thái hoạt động của đối tượng. Đối với việc thiết lập trạng thái, ta sử dụng hàm SetActive với giá trị truyền vào là true/false, là trạng thái cần thiết để thiết lập cho đối tượng đó.

Nếu đối tượng cha có trạng thái active là false thì dù bạn có thay đổi trạng thái của đối tượng con, chúng vẫn sẽ trả về giá trị false.

isStatic

Một số đối tượng trong game, ví dụ như bản đồ hay các chướng ngại vật tĩnh đều không có khả năng di chuyển. Do đó chúng ta nên thiết lập trạng thái Static cho các đối tượng đó để tiết kiệm tài nguyên. Các đối tượng Static sẽ được tiền xử lý và gom chung thành một đối tượng gọi là Batching object, nhờ đó sẽ tiết kiệm được một số lượng Draw call (Draw call là số lần render một đối tượng, mỗi lần render là một draw call).

Tương tự như trạng thái Active của đối tượng, trong Unity Editor có 1 checkbox dùng cho việc thiết lập trạng thái static của đối tượng. Thuộc tính isStatic dùng để kiểm tra trạng thái tĩnh của đối tượng, từ đó bỏ qua các thao tác xử lý với đối tượng này.

Thao tác với Component

transform

Thành phần Transform là một thành phần bắt buộc, không thể thêm hoặc xoá đối với bất kỳ GameObject nào. Transform lưu trữ các thông tin về vị trí, phép quay và tỉ lệ của đối tượng. Ngoài ra Transform còn có một số thuộc tính và phương thức hay để thao tác với GameObject. Chi tiết về các tính năng này sẽ được hướng dẫn ở một bài viết khác.

GetComponent và GetComponents

Hàm GetComponent sẽ trả về component đầu tiên cần tìm của đối tượng, trong khi GetComponents sẽ tra về một danh sách toàn bộ các component cần tìm. Nếu không tìm được sẽ trả về null hoặc mảng không có phần tử tương ứng.

Nguyên mẫu của hàm như sau:

public Component GetComponent(Type type);
public Component GetComponent(string type);

Hàm có thể nhận vào giá trị kiểu Type hoặc kiểu string đều được chấp nhận. Tuy nhiên, để tối ưu ta nên sử dụng kiểu Type trong hầu hết mọi trường hợp. Một cú pháp khác để lấy một thành phần với Type như sau:

public Type GetComponent<Type>();

Cú pháp này sử dụng template để lấy ra các component. Đây là cách thông dụng nhất được lập trình viên sử dụng trong C# Script.

Một trường hợp bắt buộc phải sử dụng string để tìm kiếm là khi cần truy xuất các lớp được định nghĩa trong C# Script bằng Javascript hoặc ngược lại. Do tính đa ngôn ngữ, Unity cho phép lập trình viên sử dụng C# hoặc Javascript để lập trình và các ngôn ngữ này không thể được liên kết trực tiếp bằng Type. Lúc này ta sẽ sử dụng string và thao tác tương tự như sau:

comp = gameObject.GetComponent("Comp") as Comp;
comp.xyz = 1.0f;

Tìm kiếm Component trong các đối tượng cha hoặc con

Unity cũng cung cấp sẵn một số phương thức giúp ta có thể thao tác được với component thuộc đối tượng cha/con của nó. Cách thức hoạt động tương tự như GetComponent và GetComponents.

Các hàm như sau:

  • GetComponentInChildren.
  • GetComponentsInChildren.
  • GetComponentInParent.
  • GetComponentsInParent.

Các hàm này chỉ có thể được sử dụng với Type của component, kiểu string không được chấp nhận.

Tìm kiếm GameObject

Tìm kiếm với name

Hàm Find được Unity thiết kế để tìm kiếm một đối tượng trong cửa sổ Hierarchy. Cú pháp của hàm như sau:

public static GameObject Find(string name);

Hàm sẽ trả về giá trị GameObject là chính đối tượng được tìm thấy, nếu không có đối tượng có tên cần tìm, hàm sẽ trả về null.

Chuỗi name truyền vào chính là tên của đối tượng cần tìm. Nếu chuỗi kí tự có chứa kí hiệu "/", Unity sẽ xem đó là đường dẫn của đối tượng ở trong cửa sổ Hierarchy.

Lưu ý: Hàm sẽ chỉ trả về đối tượng được active trong cửa sổ Hierarchy. Mọi đối tượng khác cho dù có tên đúng yêu cầu nhưng chưa được active cũng sẽ bị bỏ qua.

Tìm kiếm với tag

Để tìm kiếm với tag, ta sử dụng hàm FindGameObjectWithTag hoặc FindGameObjectsWithTag tương ứng để tìm một hay toàn bộ các đối tượng có tag cần tìm. Cách sử dụng tương tự như hàm Find đề cập ở trên, sử dụng tag để tìm kiếm đối tượng.

GameObject stdioObject = GameObject.FindGameObjectWithTag("StdioObject");

Lưu ý: Tìm kiếm với name và tag đều có thể cho ra kết quả giống nhau, nhưng về chi phí cần sử dụng thì tìm kiếm với tag sẽ tối ưu hơn. Do đó trong mọi trường hợp, bạn hãy sử dụng tag cho việc tìm kiếm nếu khả thi.

Khởi tạo và giải phóng GameObject

Khởi tạo

CreatePrimitive

Khởi tạo một đối tượng được định nghĩa sẵn bởi Unity. Đối tượng được tạo ra sẽ có sẵn Mesh Renderer và Collider tương ứng với hình dạng của đối tượng.

Cách sử dụng hàm như sau:

GameObject plane = GameObject.CreatePrimitive(PrimitiveType.Plane);

GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.transform.position = new Vector3(0, 0.5f, 0);

GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
sphere.transform.position = new Vector3(0, 1.5f, 0);

Danh sách các PrimitiveType được hỗ trợ:

Sphere

Đối tượng hình cầu, bán kính bằng 1.

Capsule

Đối tượng hình capsule.

Cylinder

Đối tượng hình trụ.

Cube

Tạo ra một khối lập phương có độ dài cạnh bằng 1.

Plane

Tạo ra một mặt phẳng, được sử dụng trong việc xây dựng map.

Quad

Đối tượng quad (4 điểm trong không gian).

Instantiate

Instantiate được sử dụng để clone một đối tượng được lập trình viên xây dựng sẵn. Nguyên mẫu hàm như sau:

public static Object Instantiate(Object original, Vector3 position, Quaternion rotation);
public static Object Instantiate(Object original);

Nếu không truyền vào position và rotation, hàm sẽ lấy các giá trị của đối tượng cơ sở để gán cho đối tượng mới, hoặc trả về Vector3.zeroQuaternion.identity nếu không khả dụng. Tìm hiểu thêm về Vector3 và Quaternion tại Vector Trong UnityC# Script - Lớp Quaternion.

Khi sử dụng Instantiate, toàn bộ các đối tượng con và cấu trúc sẽ được sao chép với đúng tính chất của chúng. Tuy nhiên, đối tượng cha (nếu có) sẽ được đặt là null. Do đó đối tượng được clone có thể sẽ không nằm chung vị trí với đối tượng ban đầu.

Instantiate cũng sao chép được các đối tượng "inactive". Tính chất này sẽ được giữ lại và bản sao được tạo ra cũng sẽ có trạng thái "inactive".

Giải phóng

Destroy

Hàm Destroy được sử dụng để giải phóng một GameObject, component hay tài nguyên được sử dụng trong game. Hàm nhận vào giá trị là đối tượng cần giải phóng, cùng với thời gian delay (mặc định là 0). Việc huỷ đối tượng sẽ được delay cho đến khi kết thúc hàm Update, nhưng đối tượng sẽ được huỷ trước quá trình render.

Dưới đây là ví dụ để bạn hiểu về chức năng và cách sử dụng hàm Destroy:

// Destroy current game object
Destroy (gameObject);

// Removes this script instance from the game object
Destroy (this);

// Removes the rigidbody from the game object
Destroy (GetComponent<BoxCollider>());
	
// Destroy the game object in 5 seconds after loading the object
Destroy (gameObject, 5);

DontDestroyOnLoad

Khi thực hiện chuyển scene, các đối tượng ở scene cũ sẽ được giải phóng hoàn toàn. Hàm này giúp chỉ định một đối tượng nào đó sẽ không bị giải phóng khi chuyển scene. Cách sử dụng hàm như sau:

DontDestroyOnLoad(targetObject);

targetObject chính là đối tượng sẽ được giữ lại khi chuyển scene. Đối tượng này vẫn có thể được giải phóng bằng hàm Destroy.

Lưu ý: Đối với các GameObject của scene, hàm chỉ có tác dụng nếu GameObject đó không là con của bất kì đối tượng nào. Toàn bộ cấu trúc và các đối tượng con của nó sẽ được giữ lại qua mọi thao tác chuyển scene.

Tổng kết

Trên đây là hầu hết các thao tác bạn sẽ gặp khi phải xử lý với bất kì GameObject nào trong game. Khi đã nắm vững các thao tác và sử dụng linh hoạt, bạn sẽ xây dựng game của mình một cách nhanh và hiệu quả nhất.

Tham khảo

http://docs.unity3d.com/ScriptReference/GameObject.html - 16/04/2016.

Bạn cần hỗ trợ các dự án kết nối không dây?

Quí doanh nghiệp, cá nhân cần hỗ trợ, hợp tác các dự án IoT, kết nối không dây. Vui lòng liên hệ, hoặc gọi trực tiếp 0942.111912.

  • TỪ KHÓA
  • Arduino
  • ESP32
  • ESP8266
  • Wifi
  • Bluetooth
  • Zigbee
  • Raspberry Pi
THẢO LUẬN
ĐÓNG