Các hàm cơ bản của Monobehaviour Unity: Awake, OnEnable, Start
Monobehaviour là một lớp “nền” cho các script được gắn vào game object trong Unity. Một lớp Mono có sẵn rất nhiều hàm để thực thi các chức năng khác nhau của một gameobject. Awake, Start, OnEnable là một trong số đó. Về cơ bản ba hàm đó đều được gọi khi một game object được tạo ra. Nhìn chung, mình thường gọi nó là các hàm khởi tạo.
Khi tạo một script bất kì trong Unity, script đó được kế thừa từ Monobehaviour và được viết sẵn hai hàm Start và Update. Các dev của Unity cũng rất cẩn thận khi comment chức năng của hai hàm đó.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
Một trong ba hàm khởi tạo nhưng hình như các dev của Unity đang gợi ý rằng chúng ta nên dùng Start. Tại sao lại như vậy? Mình tin rằng các bạn sẽ có câu trả lời trong bài viết này.
Thứ tự thực thi
Điểm mấu chốt và khác nhau rõ ràng nhất của ba hàm thực thi đó là thứ tự được gọi khi game object được tạo ra. Và thứ tự thực thi của chúng là:
Awake => OnEnable => Start
Việc thực thi, xử lý công việc phụ thuộc rất nhiều vào CPU. Unity là engine hỗ trợ build đa nền tảng. Tức là game của bạn có thể chạy trên nhiều nền tảng và nhiều hệ máy khác nhau. Điều đó cũng có nghĩa là tốc độ xử lý CPU cũng rất khác nhau.
Nếu bạn xử dụng Awake với quá nhiều gameobject cùng khởi tạo một lúc đối với các CPU yếu rất dễ dẫn đến việc bị nghẽn và bị bỏ qua.
Còn với OnEnable là hàm thực thi sau Awake tính từ khi khởi tạo game object nhưng ngoài ra OnEnable có thể được gọi trong quá trình game object hoạt động.
Do vậy, Start được cho là phương án an toàn trong việc xử lý các tác vụ của game object khi mới khởi tạo.
Sử dụng hợp lý
Như mình đã nói ở trên, sử dụng hàm Start để thực thi các tác vụ của game object khi mới được tạo ra là an toàn. Nhưng không có nghĩa là chúng ta sẽ không dùng hai hàm còn lại. Hiểu rõ và sử dụng hợp lý là cách để tránh các lỗi không mong muốn khi game chạy trên các nền tảng khác nhau.
Awake
Awake là hàm được gọi sớm nhất khi CPU bắt đầu xử lý. Giống như bạn thức dậy vào buổi sáng thì việc mở mắt chính là lúc Awake được gọi. Việc CPU phải xử lý sớm rất dễ xảy ra lỗi với các CPU trung bình yếu.
Vì vậy, mình khuyên các bạn chỉ sử dụng Awake với các game object được đặt sẵn trong Scene và quản lý hoặc tạo (Instantiate) các object khác.
Ví dụng với script GameManager của mình:
public class GameManager : MonoBehaviour
{
public AudioManager audioManager;
public InputManager inputManager;
public Character characterPrefab;
private void Awake()
{
LoadData();
InitManager();
CreatCharacter();
}
// Thực thi các tác vụ khởi tạo của Manager khác
private void InitManager()
{
audioManager.Init();
inputManager.Init();
}
// Tạo ra Character
private void CreatCharacter()
{
Character character = Instantiate(characterPrefab);
}
// Load dữ liệu
private void LoadData()
{
// Load Data
}
}
Start
Start được gọi sau khi OnEnable thực thi xong. Sử dụng Start khá an toàn và ít lỗi với các CPU so với Awake. Cũng chính vì thế mà các nhà phát triển của Unity khuyên viết các lệnh bạn muốn thực hiện khi object được khởi tạo trong hàm Start.
OnEnable
Awake và Start chỉ được gọi một lần duy nhất khi game object được tạo ra, nhưng với OnEnable thì lại khác. OnEnable được gọi bất cứ khi nào game object chuyển từ trạng thái deactive sang trạng thái active hoặc thay đổi giá trị của enable từ false sang true. Do đó, mình hầu như không dùng đến OnEnable đối với game object. Thay vào đó, đối với các object trong Canvas (UI) phải deactive với active nhiều thì OnEnable mới thực sự hữu ích.