| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 | 
							- using System;
 
- using System.Collections;
 
- using System.Collections.Generic;
 
- using UnityEngine;
 
- using YooAsset;
 
- namespace UniFramework.Pooling
 
- {
 
- 	internal class GameObjectPool
 
- 	{
 
- 		private readonly GameObject _root;
 
- 		private readonly Queue<InstantiateOperation> _cacheOperations;
 
- 		private readonly bool _dontDestroy;
 
- 		private readonly int _initCapacity;
 
- 		private readonly int _maxCapacity;
 
- 		private readonly float _destroyTime;
 
- 		private float _lastRestoreRealTime = -1f;
 
- 		/// <summary>
 
- 		/// 资源句柄
 
- 		/// </summary>
 
- 		public AssetOperationHandle AssetHandle { private set; get; }
 
- 		/// <summary>
 
- 		/// 资源定位地址
 
- 		/// </summary>
 
- 		public string Location { private set; get; }
 
- 		/// <summary>
 
- 		/// 内部缓存总数
 
- 		/// </summary>
 
- 		public int CacheCount
 
- 		{
 
- 			get { return _cacheOperations.Count; }
 
- 		}
 
- 		/// <summary>
 
- 		/// 外部使用总数
 
- 		/// </summary>
 
- 		public int SpawnCount { private set; get; } = 0;
 
- 		/// <summary>
 
- 		/// 是否常驻不销毁
 
- 		/// </summary>
 
- 		public bool DontDestroy
 
- 		{
 
- 			get { return _dontDestroy; }
 
- 		}
 
- 		public GameObjectPool(GameObject poolingRoot, string location, bool dontDestroy, int initCapacity, int maxCapacity, float destroyTime)
 
- 		{
 
- 			_root = new GameObject(location);
 
- 			_root.transform.parent = poolingRoot.transform;
 
- 			Location = location;
 
- 			_dontDestroy = dontDestroy;
 
- 			_initCapacity = initCapacity;
 
- 			_maxCapacity = maxCapacity;
 
- 			_destroyTime = destroyTime;
 
- 			// 创建缓存池
 
- 			_cacheOperations = new Queue<InstantiateOperation>(initCapacity);
 
- 		}
 
- 		/// <summary>
 
- 		/// 创建对象池
 
- 		/// </summary>
 
- 		public void CreatePool(ResourcePackage package)
 
- 		{
 
- 			// 加载游戏对象
 
- 			AssetHandle = package.LoadAssetAsync<GameObject>(Location);
 
- 			// 创建初始对象
 
- 			for (int i = 0; i < _initCapacity; i++)
 
- 			{
 
- 				var operation = AssetHandle.InstantiateAsync(_root.transform);
 
- 				operation.Completed += Operation_Completed;
 
- 				_cacheOperations.Enqueue(operation);
 
- 			}
 
- 		}
 
- 		private void Operation_Completed(AsyncOperationBase obj)
 
- 		{
 
- 			if (obj.Status == EOperationStatus.Succeed)
 
- 			{
 
- 				var op = obj as InstantiateOperation;
 
- 				if (op.Result != null)
 
- 					op.Result.SetActive(false);
 
- 			}
 
- 		}
 
- 		/// <summary>
 
- 		/// 销毁游戏对象池
 
- 		/// </summary>
 
- 		public void DestroyPool()
 
- 		{
 
- 			// 卸载资源对象
 
- 			AssetHandle.Release();
 
- 			AssetHandle = null;
 
- 			// 销毁游戏对象
 
- 			GameObject.Destroy(_root);
 
- 			foreach(var t in _cacheOperations)
 
-             {
 
- 				DestroyInstantiateOperation(t);
 
-             }
 
- 			_cacheOperations.Clear();
 
- 			SpawnCount = 0;
 
- 		}
 
- 		/// <summary>
 
- 		/// 查询静默时间内是否可以销毁
 
- 		/// </summary>
 
- 		public bool CanAutoDestroy()
 
- 		{
 
- 			if (_dontDestroy)
 
- 				return false;
 
- 			if (_destroyTime < 0)
 
- 				return false;
 
- 			if (_lastRestoreRealTime > 0 && SpawnCount <= 0)
 
- 				return (Time.realtimeSinceStartup - _lastRestoreRealTime) > _destroyTime;
 
- 			else
 
- 				return false;
 
- 		}
 
- 		/// <summary>
 
- 		/// 游戏对象池是否已经销毁
 
- 		/// </summary>
 
- 		public bool IsDestroyed()
 
- 		{
 
- 			return AssetHandle == null;
 
- 		}
 
- 		/// <summary>
 
- 		/// 回收
 
- 		/// </summary>
 
- 		public void Restore(InstantiateOperation operation)
 
- 		{
 
- 			if (IsDestroyed())
 
- 			{
 
- 				DestroyInstantiateOperation(operation);
 
- 				return;
 
- 			}
 
- 			SpawnCount--;
 
- 			if (SpawnCount <= 0)
 
- 				_lastRestoreRealTime = Time.realtimeSinceStartup;
 
- 			// 如果外部逻辑销毁了游戏对象
 
- 			if (operation.Status == EOperationStatus.Succeed)
 
- 			{
 
- 				if (operation.Result == null)
 
- 					return;
 
- 			}
 
- 			// 如果缓存池还未满员
 
- 			if (_cacheOperations.Count < _maxCapacity)
 
- 			{
 
- 				SetRestoreGameObject(operation.Result);
 
- 				_cacheOperations.Enqueue(operation);
 
- 			}
 
- 			else
 
- 			{
 
- 				DestroyInstantiateOperation(operation);
 
- 			}
 
- 		}
 
- 		/// <summary>
 
- 		/// 丢弃
 
- 		/// </summary>
 
- 		public void Discard(InstantiateOperation operation)
 
- 		{
 
- 			if (IsDestroyed())
 
- 			{
 
- 				DestroyInstantiateOperation(operation);
 
- 				return;
 
- 			}
 
- 			SpawnCount--;
 
- 			if (SpawnCount <= 0)
 
- 				_lastRestoreRealTime = Time.realtimeSinceStartup;
 
- 			DestroyInstantiateOperation(operation);
 
- 		}
 
- 		/// <summary>
 
- 		/// 获取一个游戏对象
 
- 		/// </summary>
 
- 		public SpawnHandle Spawn(Transform parent, Vector3 position, Quaternion rotation, bool forceClone, params System.Object[] userDatas)
 
- 		{
 
- 			InstantiateOperation operation;
 
- 			if (forceClone == false && _cacheOperations.Count > 0)
 
- 				operation = _cacheOperations.Dequeue();
 
- 			else
 
- 				operation = AssetHandle.InstantiateAsync();
 
- 			SpawnCount++;
 
- 			SpawnHandle handle = new SpawnHandle(this, operation, parent, position, rotation, userDatas);
 
- 			YooAssets.StartOperation(handle);
 
- 			return handle;
 
- 		}
 
- 		private void DestroyInstantiateOperation(InstantiateOperation operation)
 
- 		{
 
- 			// 取消异步操作
 
- 			operation.Cancel();
 
- 			// 销毁游戏对象
 
- 			if (operation.Result != null)
 
- 			{
 
- 				GameObject.Destroy(operation.Result);
 
- 			}
 
- 		}
 
- 		private void SetRestoreGameObject(GameObject gameObj)
 
- 		{
 
- 			if (gameObj != null)
 
- 			{
 
-                 gameObj.transform.SetParent(_root.transform, false);
 
-                 //gameObj.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
 
- 				gameObj.SetActive(false);
 
-             }
 
- 		}
 
- 	}
 
- }
 
 
  |