- vừa được xem lúc

Tối ưu với Object Pooling Pattern trong Unity

0 0 17

Người đăng: Phuong Le

Theo Viblo Asia

Phuongne, Th3 26, 2020

Vì sao phải sử dụng Object Pooling?

Trong Unity, để sinh ra một phiên bản copy của một GameObject (thường là prefab), ta sẽ sử dụng hàm Instantiate(), nếu không sử dụng bản copy đó nữa chúng ta sẽ sử dụng hàm Destroy() hay DestroyImmediate().

Hàm Instantiate() sẽ phân bổ, cấp phát tài nguyên bộ nhớ cho copied-GameObject đó, hàm Destroy() xóa bỏ các tài nguyên đã cấp phát và nếu việc này xảy ra liên tục, Garbage Collector (GC) sẽ hoạt động liên tục làm phân mảnh bộ nhớ đồng thời trong frame đó phải chờ GC xử lý xong.

image.png

Memory fragmentation

Giả sử 10 khẩu súng có hàng trăm viên đạn như Gatling Gun bắn liên tục, các viên đạn sẽ được sinh ra và xóa đi trong memory liên tục như vậy sẽ ảnh hưởng rất lớn tới performance và đè nặng công việc cho Garbage Collector.

image.png

Gatling Gun

Object Pooling Pattern sinh ra nhằm giúp chúng ta tái sử dụng được các viên đạn trong ví dụ trên và giảm thiểu memory fragmentation do GC gây ra.

Object Pooling là gì?

Về ý tưởng, Object Pooling sẽ sinh ra các objects mà ta cần sử dụng trong game trước, sau đó deactive toàn bộ objects đó nếu chưa sử dụng, điều này có thể làm chậm quá trình khởi động của game.

Như vậy, thay vì Instantiate() các objects (như bullets) vào run-time, chúng ta chỉ việc lôi chúng từ Object Pool ra rồi bật active cho object đó, tương tự, thay vì Destroy(), chúng ta sẽ deactive object đó và gửi về lại Pool.

CPU xử lý active và deactive các objects tốt hơn rất nhiều so với việc sinh ra và xóa bỏ chúng trong bộ nhớ run-time, đồng thời chúng ta cũng tối ưu được cho số lượng công việc cần xử lý cho Garbage Collector (GC).

Implement Object Pooling Pattern

Để implement pattern này có rất nhiều source ở ngoài kia, ở đây mình chỉ trình bày ý tưởng của pattern.

using System.Collections; using System.Collections.Generic; using UnityEngine; [System.Serializable]
public class Preallocation { public GameObject gameObject; public int count; public bool expandable;
} public class ObjectPool : MonoSingleton<ObjectPool>
{ public List<Preallocation> preAllocations; [SerializeField] List<GameObject> pooledGobjects; protected override void Awake() { base.Awake(); pooledGobjects = new List<GameObject>(); foreach (Preallocation item in preAllocations) { for (int i = 0; i < item.count; ++i) pooledGobjects.Add(CreateGobject(item.gameObject)); } } public GameObject Spawn(string tag) { for (int i = 0; i < pooledGobjects.Count; ++i) { if (!pooledGobjects[i].activeSelf && pooledGobjects[i].tag == tag) { pooledGobjects[i].SetActive(true); return pooledGobjects[i]; } } for (int i = 0; i < preAllocations.Count; ++i) { if (preAllocations[i].gameObject.tag == tag) if (preAllocations[i].expandable) { GameObject obj = CreateGobject(preAllocations[i].gameObject); pooledGobjects.Add(obj); obj.SetActive(true); return obj; } } return null; } GameObject CreateGobject(GameObject item) { GameObject gobject = Instantiate(item, transform); gobject.SetActive(false); return gobject; }
}
  • Awake(): sinh ra tất cả các objects cần có cho game
  • Spawn(): lấy các objects bằng tag của chúng
  • .expandable: phát sinh thêm object nếu ban đầu cấp phát cho Pool không đủ dùng.

Claims

Bài viết được đăng vào 2020, chỉ có giá trị tham khảo các bạn nhé 😉

Nguồn tham khảo

Bình luận

Bài viết tương tự

- vừa được xem lúc

Tạo setting game trên inspector.

. Chào các bạn,. Hôm nay chúng ta sẽ cùng tạo 1 setting/config cho game trên inspector nhé. Câu trả lời đó là khi chúng ta cần 1 cái gì đó để thao tác trong editor, trực quan nhất, không cần sửa code để cập nhật dữ liệu.... Và hẳn các bạn cũng từng làm việc với những value trên inspector rồi, ví dụ

0 0 22

- vừa được xem lúc

Hướng dẫn đưa nhân vật từ Mixamo vào demo.

. Chào các bạn. Bài này chúng ta chỉ tìm hiểu cách để lấy model, animation về, setting sao cho nó chạy được trong Unity để làm demo là ngon rồi nhé . Bước 1: Đăng nhập. Hãy tạo tài khoản nếu các bạn chưa có.

0 0 25

- vừa được xem lúc

Cơ bản về Rigidbody trong Unity3D

Phuong Le at 31-10-2019 - phuongne. Bài viết từ 2019 nên chỉ có giá trị tham khảo bạn nhé . . Rigidbody là gì.

0 0 18

- vừa được xem lúc

Một số folder đặc biệt trong Unity

Phuong Le 2019 - phuongne. Bài viết từ 2019 nên chỉ có giá trị tham khảo bạn nhé .

0 0 15

- vừa được xem lúc

Coroutine trong Unity là gì? Có liên quan tới Threads hay không?

Phuongne, Th11 17, 2019. Sơ qua một chút về Coroutine và StartCoroutine(.

0 0 11

- vừa được xem lúc

So sánh nhẹ Coroutine và Invoke

Phuongne - 31-10-2019. . Roài, đây sẽ là một bài viết ngắn nên mình đi vào chi tiết luôn, khởi mở đầu giới thiệu dài dòng nhá anh em. Coroutine với Invoke là gì.

0 0 17