Object Pooling - Tại sao phải sử dụng
Design pattern object pooling là một trong những pattern phổ biến nhất trong ngành công nghiệp game. Đó là một design pattern bạn phải biết nếu như bạn muốn trở thành một lập trình game.
What is the object pooling?
Object pooling là một design pattern được dùng để tái sử dụng object trong game của bạn. Recycling có ý nghĩ gì ? Chúng ta hãy lấy ví dụ cơ bản về bullet.
Chúng ta có một tình huống đơn giản, khi mà bạn đang bắn những viên đạn. Mỗi lần bạn nhấn nút bắn, một viên đạn sẽ được tạo ra. Nếu trong suốt trận chiến của bạn, bạn nhấn 1000 lần thì 1000 viên đạn sẽ được tao ra.
Nếu bạn suy nghĩ kỹ hơn về vấn đề này, bạn sẽ thấy không hiệu quả vì mỗi lần bắn, một đối tượng sẽ được chỉ định một vùng nhớ cái sẽ bị huỷ đi sau đó. Vậy có cách nào khác tốt hơn không ?
Sử dụng Object pooding
Đây là cách mà nó làm việc:
1. Tạo một vùng chứa (pool) những viên đạn ở nơi nào đó trong game của bạn
2. Mỗi lần chúng ta bắn, chúng ta sẽ lấy một viên đạn từ vùng chứa đó
3. Bắn viên đạn vửa lấy ra
4. Khi viên đạn trúng mục tiêu, thay vì huỷ (destroy) nó, chúng ta duy chuyển nó lại vùng chứa.(pool)
Tại sao lại sử dụng object pooling?
Mục đích của việc sử dụng object pooling là để cải thiện hiệu năng. Nếu không sử dụng object pooling, bạn vẫn có thể tạo một đối tượng mỗi lần bạn muốn sử dụng. Điệu này xảy ra tại runtime, có thể việc quản lý bộ nhớ sẽ không hiệu quả, đặc biệt trọng ngôn ngữ với garbage collector như C#.
Nếu sử dụng object pool, bạn sẽ tạo tất cả các đối tượng bạn muốn sử dụng ở game start. Sau đó chúng ta sẽ luôn luôn tái sử dụng tất cả các đối tượng đó, sẽ không cần quản lý bộ nhớ quá nhiều, và không cần phải tạo một đối tượng mới.
Ví dụ object pooling trong Unity C#
Bước 1: Tạo một nơi chứa các đối tượng
Trong bước đầu tiên, trong unity editor chúng ta sẽ tạo một tập các đối tượng, những cái được sử dụng cho việc tái sử dụng.
Như các bạn thấy, chúng ta tạo một GameObject có tên là pool bao gồm 1 tập hợp các đối tượng được tái sử dụng. Để bạn có thể thấy cách làm việc của object pool, chúng ta di chuyển chúng tới cạnh bên trên và bên phải màn hình.
Bước 2: Logic của Object pooling
Chúng ta sẽ tạo một file script để sử dụng pool cho object. Script này sẽ có các tác vụ rõ ràng :
1. Chúng ta sẽ lấy một đối tượng random từ pool
2. Di chuyển đối tượng đến trung tâm của màn hình
3. Sau 1 giây chúng ta sẽ set lại đối tượng quay trở lại pool
using UnityEngine;
using System.Collections.Generic;
using System.Collections;
public class ObjectPoolingManager : MonoBehaviour
{
#region FIELDS
public List objectToRecycle = new List(); // Used to keep traking od the objects that we can use in the game
public Transform originlPoolPosition; // used to reset the position of the object that we've pulled
private GameObject _selectedObject;
#endregion
#region MONOBHEAVIOR
void Start()
{
InvokeRepeating("Shot", 1.0f, 2f); //Shot an object every 2 seconds
}
private void Shot()
{
SetObjectFromPools();
_selectedObject.transform.position = Vector3.zero; // Move the object to the center
StartCoroutine(ResetTheObject());
}
//Get an object from the pool and remove it from the pool once is selected
private void SetObjectFromPools()
{
_selectedObject = this.objectToRecycle[this.objectToRecycle.Count - 1];
this.objectToRecycle.Remove(this.selectedObject);
}
//Readd the object to the pool and reset his position
private IEnumerator ResetTheObject()
{
yield return new WaitForSeconds(1);
_selectedObject.transform.position = originlPoolPosition.position;
this.objectToRecycle.Add(this.selectedObject);
}
#endregion
}
Script này chính xác là những gì chúng ta cần làm.
What is the object pooling?
Object pooling là một design pattern được dùng để tái sử dụng object trong game của bạn. Recycling có ý nghĩ gì ? Chúng ta hãy lấy ví dụ cơ bản về bullet.
Chúng ta có một tình huống đơn giản, khi mà bạn đang bắn những viên đạn. Mỗi lần bạn nhấn nút bắn, một viên đạn sẽ được tạo ra. Nếu trong suốt trận chiến của bạn, bạn nhấn 1000 lần thì 1000 viên đạn sẽ được tao ra.
Nếu bạn suy nghĩ kỹ hơn về vấn đề này, bạn sẽ thấy không hiệu quả vì mỗi lần bắn, một đối tượng sẽ được chỉ định một vùng nhớ cái sẽ bị huỷ đi sau đó. Vậy có cách nào khác tốt hơn không ?
Sử dụng Object pooding
Đây là cách mà nó làm việc:
1. Tạo một vùng chứa (pool) những viên đạn ở nơi nào đó trong game của bạn
2. Mỗi lần chúng ta bắn, chúng ta sẽ lấy một viên đạn từ vùng chứa đó
3. Bắn viên đạn vửa lấy ra
4. Khi viên đạn trúng mục tiêu, thay vì huỷ (destroy) nó, chúng ta duy chuyển nó lại vùng chứa.(pool)
Tại sao lại sử dụng object pooling?
Mục đích của việc sử dụng object pooling là để cải thiện hiệu năng. Nếu không sử dụng object pooling, bạn vẫn có thể tạo một đối tượng mỗi lần bạn muốn sử dụng. Điệu này xảy ra tại runtime, có thể việc quản lý bộ nhớ sẽ không hiệu quả, đặc biệt trọng ngôn ngữ với garbage collector như C#.
Nếu sử dụng object pool, bạn sẽ tạo tất cả các đối tượng bạn muốn sử dụng ở game start. Sau đó chúng ta sẽ luôn luôn tái sử dụng tất cả các đối tượng đó, sẽ không cần quản lý bộ nhớ quá nhiều, và không cần phải tạo một đối tượng mới.
Ví dụ object pooling trong Unity C#
Bước 1: Tạo một nơi chứa các đối tượng
Trong bước đầu tiên, trong unity editor chúng ta sẽ tạo một tập các đối tượng, những cái được sử dụng cho việc tái sử dụng.
Như các bạn thấy, chúng ta tạo một GameObject có tên là pool bao gồm 1 tập hợp các đối tượng được tái sử dụng. Để bạn có thể thấy cách làm việc của object pool, chúng ta di chuyển chúng tới cạnh bên trên và bên phải màn hình.
Bước 2: Logic của Object pooling
Chúng ta sẽ tạo một file script để sử dụng pool cho object. Script này sẽ có các tác vụ rõ ràng :
1. Chúng ta sẽ lấy một đối tượng random từ pool
2. Di chuyển đối tượng đến trung tâm của màn hình
3. Sau 1 giây chúng ta sẽ set lại đối tượng quay trở lại pool
using UnityEngine;
using System.Collections.Generic;
using System.Collections;
public class ObjectPoolingManager : MonoBehaviour
{
#region FIELDS
public List objectToRecycle = new List(); // Used to keep traking od the objects that we can use in the game
public Transform originlPoolPosition; // used to reset the position of the object that we've pulled
private GameObject _selectedObject;
#endregion
#region MONOBHEAVIOR
void Start()
{
InvokeRepeating("Shot", 1.0f, 2f); //Shot an object every 2 seconds
}
private void Shot()
{
SetObjectFromPools();
_selectedObject.transform.position = Vector3.zero; // Move the object to the center
StartCoroutine(ResetTheObject());
}
//Get an object from the pool and remove it from the pool once is selected
private void SetObjectFromPools()
{
_selectedObject = this.objectToRecycle[this.objectToRecycle.Count - 1];
this.objectToRecycle.Remove(this.selectedObject);
}
//Readd the object to the pool and reset his position
private IEnumerator ResetTheObject()
{
yield return new WaitForSeconds(1);
_selectedObject.transform.position = originlPoolPosition.position;
this.objectToRecycle.Add(this.selectedObject);
}
#endregion
}
Script này chính xác là những gì chúng ta cần làm.
Comments
Post a Comment