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);
- }
- }
- }
- }
|