Unity Practices.
Bài đăng này đã không được cập nhật trong 9 năm
Unity là 1 engine để làm game nổi tiếng được dùng rất nhiều trên thế giới, nếu là game developer không thể không nghe nói đến Unity. Unity có thể giúp hoàn thành 1 game trong thời gian ngắn với số lượng members ít, nhờ số lượng asset có sẵn và những API được tích hơp từ đầu. Tuy nhiên Unity không phải hoàn hảo, với những project lớn, nhiều members và làm trong thời gian dài, Unity rất khó kiểm soát, cả trong quá trình development và maintain, sau đây là những practices được dùng cho Unity nhằm mục đích tránh tối đa vấn đề có thể xảy ra, là điều mà bất kỳ Unity developer cần được biết.
-
Tránh branching cho asset, nên chỉ để lại 1 phiên bản cho các asset. Nếu đã bắt buộc cần phải chia branch cho prefab, scene hay mesh, phải xác định rõ ràng những asset đó thuộc phiên bản nào.
-
Mỗi member tham gia dự án cần có 1 bản copy thứ 2 của project để checkout để test, sau khi thay đổi, bản copy thứ 2 sẽ được update và test, không ai nên đông đến bản copy gốc, điều này sẽ giúp tìm ra những asset bị thiếu.
-
Hãy nghĩ tới việc sử dụng những tool thiết kế level ngoài, bởi tool của Unity không được tốt, như trong trường hợp mình muốn dựng game chiến thuật với bản đồ ô, hay instantiate prefabs từ file XML.
-
Hãy nghĩ tới việc save các levels trong XML thay bằng trong Scene, đây là 1 kỹ thuật tuyệt vời:
- Điều này khiến việc chỉnh sửa scene không cần thiết.
- Khiến load nhanh hơn (khi các object được chia sẽ giữa các scenes).
- Dễ merge các scene lại hơn.
- Dễ kiếm soát dữ liệu giữa các scene hơn.
Scene Organization
-
Hãy sử dụng game object rỗng để tạo ra thư mục trong scene, sắp xếp các object sao cho việc tìm ra chúng dễ hơn.
-
Hãy đặt các manager prefab và folder prefab (prefab rỗng) tại Vector3(0, 0, 0). Khiến khả năng xung đột giữa local và world space thấp hơn, và cũng khiến coding dễ dàng hơn.
-
Hãy đặt nền thế giới (y = 0), sẽ khiến việc đặt các object xuống nền dễ hơn, và hãy đối xử với thế giới như 1 không gian 2D cho các game logic, AI và vật lý.
-
Quan trọng, hãy khiến game có thể chạy được từ bất kỳ scene nào, điều này giảm tối thiếu thời gian test, để làm điều đó những điều cần sau đây:
- Cung cấp data giả cần thiết để load scene trong trường hợp khi nó không có.
- Hãy spawn những object cần thiết giữa 2 scene như sau đây.
myObject = FindMyObjectInScene ();
if (!myObject) {
myObject = SpawnMyObject ();
}
Art
-
Hãy đặt các nhân vật và các vật đứng đúng trục tại điểm trụ, không phải tại trung tâm, sẽ khiến việc đặt chúng lên nền dễ dàng hơn. Đồng thời cũng sẽ khiến việc làm việc với 3D trong 2D dễ dàng hơn, AI và thậm chí cả logic, vật lý.
-
Hãy đặt các mesh quay vào cùng hướng (âm hay dương trục z), nhiều tính toán được đơn giản hóa đi nếu mọi thứ xoay vào cùng 1 hướng.
-
Hãy xác định kích cỡ cho các object ngay từ đầu, tạo ra các mesh để chúng có thể được import dưới kích cỡ 1 trên 1. Hãy so sánh với cube của Unity để so sánh kích cỡ dễ dàng hơn.
Prefab
-
Hãy dùng prefab cho tất cả mọi thứ, thứ duy nhất trong scene không dùng prefab là các folders. Ngay đến các object mà chỉ được dùng 1 lần cũng nên là prefab, điều này khiến việc modify object không ảnh hưởng đến cene.
-
Hãy tạo các prefab khác biệt cho những instance đồng component, nếu có 2 loại đối phương và chúng chỉ khác nhau với các properties, tạo ra separate rời và kết nối chúng, điều này khiến:
- Thay đổi cho mọi loại tại 1 điểm.
- Thay đổi mà không cần gây ảnh hưởng đến scene.
- Hãy dùng branching 1 cách an toàn, như cách branch prefab Player sau đây.
- Tạo copy của Player.
- Thay đổi tên bản sao thành __Player_Backup.
- Thay đổi bản gốc Player.
- Nếu mọi thứ hoạt động như ý muốn, xóa copy backup đi.
Đừng đặt tên của bản sao Player thành Player_New và thay đổi nó. Trong 1 số trường hợp có thể phức tạp hơn, khi sự thay đổi có thể liên quan đến nhiều người và việc modify có thể dẫn đến scene không còn hoạt động cho người khác, có thể dùng cách sau đây.
Người thứ nhất:
- Tạo copy prefab Player.
- Đổi tên thành __Player_NewFeature hoặc __Player_ForName với tên người kia.
- Thay đổi và commit.
Người thứ hai:
- Thay đổi cho prefab mới.
- Tạo copy cho Player, đặt tên nó __Player_Backup.
- Kéo instance của __Player_NewFeature vào scene.
- Kéo instance của Player gốc vào scene.
- Nếu mọi thứ hoạt động xóa __Player_NewFeature và __Player_Backup.
-
Tạo ra class time riêng sẽ khiến việc pause game dễ hơn, gói Time.DeltaTime và Time.TimeSinceLevelLoad với logic pause và time scale, tuy tạo khó khan ban đầu nhưng sẽ khiến mọi thứ đơn giản hơn, nhất là với nhiều thời gian khác nhau.
-
Đừng spawn object trong hierarchy khi game chạy, hãy đặt cho nó 1 object cha để dễ tìm và kiểm soát trong lúc game chạy.
-
Hãy dùng Singleton để đơn giản hóa, class sau đây sẽ khiến cho tất cả class kế thừa từ nó tự động thành singleton.
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour {
protected static T instance;
public static T Instance {
get {
if(instance == null)
{
instance = (T) FindObjectOfType(typeof(T));
if (instance == null)
{
Debug.LogError("An instance of " + typeof(T) +
" is needed in the scene, but there is none.");
}
}
return instance;
}
}
Tại đây kết thúc phần thứ nhất của Unity Practices, phần tiếp theo sẽ đi sâu hơn vào coding, mô tả những practices nên dùng khi viết code C# trong Unity, và những gì tuyệt đối nên hạn chế.
All rights reserved