ObjectPoolManager增加异步加载API
ResourceObj类增加用于异步回调的参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class ResourceObj {
public bool m_SetSceneParent = false; public OnAsyncObjFinish m_DealFinish = null; public object m_Param1, m_Param2, m_Param3;
public void Reset() { m_SetSceneParent = false; m_DealFinish = null; m_Param1 = null; m_Param2 = null; m_Param3 = null; } }
|
添加AsyncInstantiateObject方法和回调方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
| public void AsyncInstantiateObject( string path, OnAsyncObjFinish dealFinish, LoadResPriority priority, bool setSceneObj = false, object param1 = null, object param2 = null, object param3 = null, bool bClear = true, bool isSprite = false) { if (string.IsNullOrEmpty(path)) { return; } uint crc = CRC32.GetCRC32(path); ResourceObj resObj = GetObjectFromDicCache(crc); if (resObj != null) { if (setSceneObj) { resObj.m_CloneObj.transform.SetParent(SceneTrans, false); } if(dealFinish != null) { dealFinish.Invoke(path, resObj.m_CloneObj, param1, param2, param3); } return; }
resObj = m_ResourceObjPool.Spawn(true); resObj.m_Crc = crc; resObj.m_SetSceneParent = setSceneObj; resObj.m_bClear = bClear; resObj.m_DealFinish = dealFinish; resObj.m_Param1 = param1; resObj.m_Param2 = param2; resObj.m_Param3 = param3; ResourceManager.Instance.AsyncLoadPoolResource(path, resObj, OnLoadResourceObjFinish, priority, isSprite); } void OnLoadResourceObjFinish(string path, ResourceObj resObj, object param1 = null, object param2 = null, object param3 = null) { if (resObj == null) { return; } if(resObj.m_ResItem.m_Obj == null) { #if UNITY_EDITOR Debug.LogError("异步加载的资源为空:" + path); #endif } else { resObj.m_CloneObj = GameObject.Instantiate(resObj.m_ResItem.m_Obj) as GameObject; } if (resObj.m_CloneObj != null && resObj.m_SetSceneParent) { resObj.m_CloneObj.transform.SetParent(SceneTrans,false); } if (resObj.m_DealFinish != null) { int tempGUID = resObj.m_CloneObj.GetInstanceID(); if (!m_ResourceObjDic.ContainsKey(tempGUID)) { m_ResourceObjDic.Add(tempGUID, resObj); } resObj.m_DealFinish(path,resObj.m_CloneObj,resObj.m_Param1,resObj.m_Param2,resObj.m_Param3); } }
|
ResourceManager增加用于对象池异步加载的API
增加用于对象池异步加载的回调
1
| public delegate void OnAsyncPoolObjFinish(string path, ResourceObj resObj, object param1 = null, object param2 = null, object param3 = null);
|
AsyncCallBack回调类增加回调引用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class AsyncCallBack { public OnAsyncObjFinish m_DealFinish = null;
public OnAsyncPoolObjFinish m_PoolDealFinish = null; public ResourceObj m_ResObj = null;
public object m_Param1 = null; public object m_Param2 = null; public object m_Param3 = null; public void Reset() { m_DealFinish = null; m_PoolDealFinish = null; m_ResObj = null; m_Param1 = null ; m_Param2 = null ; m_Param3 = null ; } }
|
添加AsyncLoadPoolResource方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
public void AsyncLoadPoolResource(string path, ResourceObj resObj, OnAsyncPoolObjFinish dealFinish, LoadResPriority priority, bool isSprite = false) { ResourceItem item = GetCacheResourceItem(resObj.m_Crc); if (item != null) { resObj.m_ResItem = item; if (dealFinish != null) { dealFinish(path, resObj,resObj.m_Param1,resObj.m_Param2,resObj.m_Param3 ); } return; }
AsyncLoadResParam para = null; if (!m_LoadingAssetDic.TryGetValue(resObj.m_Crc, out para) || para == null) { para = m_AsyncLoadResParamPool.Spawn(true); para.m_Crc = resObj.m_Crc; para.m_Path = path; para.m_isSprite = isSprite; para.m_Priority = priority; m_LoadingAssetDic.Add(resObj.m_Crc, para); m_LoadingAssetList[(int)priority].Add(para); }
AsyncCallBack callBack = m_AsyncCallBackPool.Spawn(true); callBack.m_PoolDealFinish = dealFinish; callBack.m_ResObj = resObj; para.m_CallBackList.Add(callBack); }
|
在异步协程中添加Pool回调的调用方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| IEnumerator AsyncLoadCor() { List<AsyncCallBack> callBackList = null; long lastYieldTime = System.DateTime.Now.Ticks; while(true) { bool haveYield =false; for (int i = 0; i < (int)LoadResPriority.RES_NUM; i++) { for (int j = 0; j < callBackList.Count; j++) { AsyncCallBack callBack = callBackList[j]; if (callBack != null && callBack.m_PoolDealFinish != null && callBack.m_ResObj != null) { ResourceObj tempResObj = callBack.m_ResObj; tempResObj.m_ResItem = resItem; callBack.m_PoolDealFinish(loadingItem.m_Path, tempResObj, tempResObj.m_Param1, tempResObj.m_Param2, tempResObj.m_Param3); callBack.m_PoolDealFinish = null; tempResObj = null; } if(callBack != null && callBack.m_DealFinish != null) { } } } } }
|
一些解释
Object Pool Manger的OnLoadResourceObjFinish
方法匹配的是OnAsyncPoolObjFinish
回调。
OnAsyncPoolObjFinish
回调是在Resource Manager的协程里面调用的。
ResourceObj内部引用的是OnAsyncObjFinish
回调
所以在OnAsyncPoolObjFinish
调用之后,返回的ResourceObj需要再调用OnAsyncObjFinish
回调
异步加载演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| using UnityEngine;
public class GameStart : MonoBehaviour { private GameObject m_GameObject; private void Awake() { DontDestroyOnLoad(gameObject); AssetBundleManager.Instance.LoadAssetBundleConfig(); ResourceManager.Instance.Init(this); ObjectPoolManager.Instance.Init(transform.Find("RecyclePoolTrans"),transform.Find("SceneTrans")); } private void Start() { ObjectPoolManager.Instance.AsyncInstantiateObject("Assets/Prefabs/Attack.prefab",OnLoadFinish,LoadResPriority.RES_HIGH,true); } void OnLoadFinish(string path,Object obj,object param1 = null, object param2 = null, object param3 = null) { m_GameObject = obj as GameObject; } private void Update() { if(Input.GetKeyDown(KeyCode.A)) { ObjectPoolManager.Instance.ReleaseObject(m_GameObject); m_GameObject = null; } else if (Input.GetKeyDown(KeyCode.D)) { ObjectPoolManager.Instance.AsyncInstantiateObject("Assets/Prefabs/Attack.prefab", OnLoadFinish, LoadResPriority.RES_HIGH, true); } else if (Input.GetKeyDown(KeyCode.S)) { ObjectPoolManager.Instance.ReleaseObject(m_GameObject, 0, true); m_GameObject = null; } } private void OnApplicationQuit() { ResourceManager.Instance.ClearCache(); Resources.UnloadUnusedAssets(); } }
|