预加载
在ObjectPoolManager
添加API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
public void PreloadGameObject(string path,int count = 1,bool clear = false) { List<GameObject> tempGameObjectList = new List<GameObject>(count); for (int i = 0; i < count; i++) { GameObject obj = InstantiateObject(path, false, bClear:clear); tempGameObjectList.Add(obj); } for (int i = 0; i < count; i++) { GameObject obj = tempGameObjectList[i]; ReleaseObject(obj); obj = null; } tempGameObjectList.Clear(); }
|
注意ReleaseObject
的参数是默认的,这意味着预加载对象的对象池缓存是无限的,还必须有回收的父级
预加载示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 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.PreLoadGameObject("Assets/Prefabs/Attack.prefab",20); } }
|
对象池取消异步加载
如果一个对象在异步加载的过程中不需要了(比如多人游戏中其他玩家一闪而过),那么就需要异步加载。
为了准确取消每个异步加载方法,我们需要让每个对象池的异步加载方法都返回一个GUID。
我们让Resource Manager提供一个方法来返回这个GUID
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class ResourceManager : SingletonPattern<ResourceManager> { protected long m_Guid = 0; public long CreateGuid() { return m_Guid++; } }
|
修改ObjectPool manager的异步加载方法AsyncInstantiateObject
,让它能返回自己的GUID
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
| protected Dictionary<long,ResourceObj> m_AsyncResObjs = new Dictionary<long,ResourceObj>();
public long AsyncInstantiateObject(//++ string path, OnAsyncObjFinish dealFinish, LoadResPriority priority, bool setSceneObj = false, object param1 = null, object param2 = null, object param3 = null, bool bClear = true) { if (string.IsNullOrEmpty(path)) { return 0; } if (resObj != null) { if(dealFinish != null) { dealFinish.Invoke(path, resObj.m_CloneObj, param1, param2, param3); } return resObj.m_Guid; }
long guid = ResourceManager.Instance.CreateGuid();
ResourceManager.Instance.AsyncLoadPoolResource(path, resObj, OnLoadResourceObjFinish, priority); m_AsyncResObjs.Add(guid, resObj); return guid; }
void OnLoadResourceObjFinish(string path, ResourceObj resObj, object param1 = null, object param2 = null, object param3 = null) { if(resObj.m_ResItem.m_Obj == null) {
} else { } if(m_AsyncResObjs.ContainsKey(resObj.m_Guid)) { m_AsyncResObjs.Remove(resObj.m_Guid); } }
|
Resource Manager添加取消异步加载API
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
|
public bool CancelAsyncLoad(ResourceObj res) { AsyncLoadResParam para = null; if (m_LoadingAssetDic.TryGetValue(res.m_Crc, out para) && m_LoadingAssetList[(int)para.m_Priority].Contains(para)) { for (int i = para.m_CallBackList.Count - 1; i >= 0; i--) { AsyncCallBack tempCallBack = para.m_CallBackList[i]; if (tempCallBack != null && res == tempCallBack.m_ResObj) { tempCallBack.Reset(); m_AsyncCallBackPool.Recycle(tempCallBack); para.m_CallBackList.Remove(tempCallBack); } } if (para.m_CallBackList.Count <= 0) { para.Reset(); m_LoadingAssetList[(int)(para.m_Priority)].Remove(para); m_AsyncLoadResParamPool.Recycle(para); m_LoadingAssetDic.Remove(res.m_Crc); return true; } } return false; }
|
在上述代码中。m_LoadingAssetList[(int)para.m_Priority].Contains(para)
用来判断此资源对象是否已经在异步加载协程中完成了。
加载一种资源只会生成一个AsyncLoadResParam
对象,但是这个对象可以有很多个AsyncCallBack
(有多个地方请求了这个资源对象),当我们取消异步加载时,如果这个资源已经加载完毕,我们只能删除后续的CallBack(可以看到我们是将para.m_CallBackList
反向移除的);除非这个资源没有被加载出来过,此时para.m_CallBackList.Count <= 0
,这才是真正取消异步加载,我们返回true。
不过在实际使用中,一旦一个资源被加载出来,所有的CallBack都会同时触发,不会出现上述前面CallBack已经触发后面CallBack没有触发的情况
Object Pool Manager添加取消异步加载的API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
public void CancelAsyncLoad(long guid) { ResourceObj resObj = null; if(m_AsyncResObjs.TryGetValue(guid, out resObj) && ResourceManager.Instance.CancelAsyncLoad(resObj)) { m_AsyncResObjs.Remove(guid); resObj.Reset(); m_ResourceObjPool.Recycle(resObj); } }
|