Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Следующий класс PoolManager управляет пулами различных объектов. Класс статический для упрощения доступа к объектам, т.е. не нужно создавать синглтоны, инстансы и прочее.
public sealed class PoolObject : MonoBehaviour {
public PoolContainer Pool { get; private set; }
public Transform CachedTransform { get; private set; }
void Awake () {
CachedTransform = transform;
}
public void SetPool (PoolContainer pool) {
Pool = pool;
}
public void Recycle () {
if (Pool != null) {
Pool.Recycle (this);
}
}
public void SetActive (bool state) {
gameObject.SetActive (state);
}
}
public sealed class PoolContainer : MonoBehaviour {
readonly Stack<PoolObject> _store = new Stack<PoolObject> (64);
GameObject _prefab;
public string PrefabPath = "UnknownPrefab";
bool LoadPrefab () {
_prefab = Resources.Load<GameObject> (PrefabPath);
if (_prefab == null) {
Debug.LogWarning ("Cant load asset " + PrefabPath);
return false;
}
#if UNITY_EDITOR
if (_prefab.GetComponent <PoolObject> () != null) {
Debug.LogWarning ("PoolObject cant be used on prefabs");
_prefab = null;
UnityEditor.EditorApplication.isPaused = true;
return false;
}
#endif
return true;
}
public PoolObject Get () {
if (_prefab == null) {
if (!LoadPrefab ()) {
return null;
}
}
PoolObject obj;
if (_store.Count > 0) {
obj = _store.Pop ();
} else {
var go = Instantiate<GameObject> (_prefab);
obj = go.AddComponent<PoolObject> ();
obj.SetPool (this);
}
obj.SetActive (false);
return obj;
}
public void Recycle (PoolObject obj) {
if (obj != null && obj.Pool == this) {
obj.SetActive (false);
if (!_store.Contains (obj)) {
_store.Push (obj);
}
} else {
#if UNITY_EDITOR
Debug.LogWarning ("Invalid obj to recycle", obj);
#endif
}
}
}
public sealed class RecycleAfterTime : MonoBehaviour {
public float Timeout = 1f;
float _endTime;
PoolObject _poolObject;
void OnEnable () {
_endTime = Time.time + Timeout;
}
void LateUpdate () {
if (Time.time >= _endTime) {
OnRecycle ();
}
}
void OnRecycle () {
var poolObj = GetComponent <PoolObject> ();
if (poolObj != null) {
poolObj.Recycle ();
} else {
gameObject.SetActive (false);
}
}
}
Простой пул объектов в Unity3D