Пул объектов позволяет сократить время создания объектов благодаря повторному использованию уже существующих объектов вместо создания новых каждый раз.
Работа с пулом состоит из следующих этапов:
- Предсоздание необходимых на старте игры объектов
- Создание объекта
- Возвращение в пул
- Сброс состояния объекта
Пул реализуется 3-мя файлами:
-
Интерфейс, который реализую все объекты, использующие пул:
public interface IPoolable { void OnReturnToPool(); }
-
Файл, реализующий интерфейс IPoolable (Пример ниже)
public class SearchingWheelLooses : MonoBehaviour, IPoolable { public SuperTextMesh textMesh; public voidSetText(string text) { textMesh.enabled = true; textMesh.Text = text; } public void OnReturnToPool() { textMesh.enabled = false; } }
-
Сам пул объектов
public class PoolObjects : MonoBehaviour
{
public PoolObjectsInstance;
public List<GameObject> prefabs = new List<GameObject>();
public static readonly Dictionary<Type, Queue<MonoBehaviour>> pool = new Dictionary<Type, Queue<MonoBehaviour>>();
void Start()
{
Instance = this;
}
public static T Get<T>() whereT : MonoBehaviour, IPoolable
{
Type typeObject = typeof(T);
if (pool.ContainsKey(typeObject))
{
if (pool[typeObject] != null && pool[typeObject].Count > 0)
{
IPoolable pO = pool[typeObject].Dequeue() asT;
return pO asT;
}
else
return Create<T>();
}
else
{
return Create<T>();
}
}
public static T Create<T>;() whereT : MonoBehaviour, IPoolable
{
foreach (var prefab inInstance.prefabs)
{
if (prefab == null)
{
Debug.LogError("Prefab is missing");
continue;
}
var poolable = prefab.GetComponent<T>();
if (poolable != null)
{
var poolableObject = Instantiate(prefab);
poolableObject.transform.SetParent(Instance.transform, Vector3.zero);
IPoolable pO = poolableObject.GetComponent<T>();
return pO as T;
}
}
Debug.LogWarning(";Prefab list not exist " + typeof(T));
return null;
}
public static void Release<T>(T poolableObject) whereT : MonoBehaviour, IPoolable
{
Type typeObject = poolableObject.GetType();
poolableObject.transform.SetParent(Instance.transform, Vector3.zero, Vector3.one);
if (pool.ContainsKey(typeObject))
{
if (!pool[typeObject].Contains(poolableObject))
pool[typeObject].Enqueue(poolableObject);
}
else
{
pool.Add(typeObject, new Queue<MonoBehaviour>());
pool[typeObject].Enqueue(poolableObject);
}
poolableObject.OnReturnToPool();
}
public static void Preload<T>(int count) whereT : MonoBehaviour, IPoolable
{
List<T>list = new List<T>(count);
for (int i = 0; i < list.count; i++)
list.Add(Get<T>(Instance.transform));
for (int i = 0; i < list.count; i++)
Release(list[i]);
}
}
Задание
Модифицировать данный пул так чтобы:
- Добавить в методы, реализующие интерейс метод OnReturnFromPool()и вызывать его в момент возвращения элемента из пула.
- Внедрить пул в проект со звездолетом, изменив способ создания врагов с простого Instantiate на пул.